Embedding a case label in an if…else statement

后端 未结 2 628
既然无缘
既然无缘 2021-01-05 07:17

G++ accepts this code and it behaves as I\'d expect it to:

#include 

void example (int value, bool condition) {

  switch (value) {
  case 0:         


        
相关标签:
2条回答
  • 2021-01-05 07:27

    What you are doing is perfectly standard C++ code, although I don't think it is particularly easy to read or maintain. If we look at the draft C++ standard section 6.4 Selection statements the grammar for switch statement is as follows:

    switch ( condition ) statement
    

    statements include labels, if, while, for etc... and section 6.4.2 The switch statement poses no restrictions that would preclude the code that you are showing.

    Case labels are just like the labels used with a goto, which is covered in section 6.1 Labeled statement but they are restricted to being used in a switch statement:

    Case labels and default labels shall occur only in switch statements.

    and section 6.7 says we can transfer into a block given some restrictions such as not bypassing a declaration with an initialization:

    It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps87 from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer (8.5).

    footnote 87 says:

    The transfer from the condition of a switch statement to a case label is considered a jump in this respect.

    Probably, one of the most famous and strangest uses of a switch statement would be Duff's device which has an embedded while loop:

    void send( int *to, const int *from, int  count)
    {
            int n = (count + 7) / 8;
            switch(count % 8) 
            {
                case 0: do {    *to = *from++;   // <- Scope start
                case 7:         *to = *from++;
                case 6:         *to = *from++;
                case 5:         *to = *from++;
                case 4:         *to = *from++;
                case 3:         *to = *from++;
                case 2:         *to = *from++;
                case 1:         *to = *from++;
                            } while(--n > 0);    // <- Scope end
            }
    }
    
    0 讨论(0)
  • 2021-01-05 07:42

    As far as C++ is concerned (draft N3936):

    • case and default labels in themselves do not alter the flow of control, which continues unimpeded across such labels.
    • Usually, the substatement that is the subject of a switch is compound and case and default labels appear on the top-level statements contained within the (compound) substatement, but this is not required.(§ 6.4.2 - 6)
    • It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. (§ 6.7 - 3)

    What you are doing is technically ok, of course that doesn't mean you should.

    0 讨论(0)
提交回复
热议问题