Why can't variables be declared in a switch statement?

后端 未结 23 2853
一生所求
一生所求 2020-11-21 05:15

I\'ve always wondered this - why can\'t you declare variables after a case label in a switch statement? In C++ you can declare variables pretty much anywhere (and declaring

相关标签:
23条回答
  • 2020-11-21 05:59

    My favorite evil switch trick is to use an if(0) to skip over an unwanted case label.

    switch(val)
    {
    case 0:
    // Do something
    if (0) {
    case 1:
    // Do something else
    }
    case 2:
    // Do something in all cases
    }
    

    But very evil.

    0 讨论(0)
  • 2020-11-21 06:01

    The entire section of the switch is a single declaration context. You can't declare a variable in a case statement like that. Try this instead:

    switch (val)  
    {  
    case VAL:
    {
      // This will work
      int newVal = 42;
      break;
    }
    case ANOTHER_VAL:  
      ...
      break;
    }
    
    0 讨论(0)
  • 2020-11-21 06:02

    If your code says "int newVal=42" then you would reasonably expect that newVal is never uninitialised. But if you goto over this statement (which is what you're doing) then that's exactly what happens - newVal is in-scope but has not been assigned.

    If that is what you really meant to happen then the language requires to make it explicit by saying "int newVal; newVal = 42;". Otherwise you can limit the scope of newVal to the single case, which is more likely what you wanted.

    It may clarify things if you consider the same example but with "const int newVal = 42;"

    0 讨论(0)
  • 2020-11-21 06:02

    I believe the issue at hand is that is the statement was skipped, and you tried to use the var elsewhere, it wouldn't be declared.

    0 讨论(0)
  • 2020-11-21 06:04

    Ok. Just to clarify this strictly has nothing to do with the declaration. It relates only to "jumping over the initialization" (ISO C++ '03 6.7/3)

    A lot of the posts here have mentioned that jumping over the declaration may result in the variable "not being declared". This is not true. An POD object can be declared without an initializer but it will have an indeterminate value. For example:

    switch (i)
    {
       case 0:
         int j; // 'j' has indeterminate value
         j = 0; // 'j' set (not initialized) to 0, but this statement
                // is jumped when 'i == 1'
         break;
       case 1:
         ++j;   // 'j' is in scope here - but it has an indeterminate value
         break;
    }
    

    Where the object is a non-POD or aggregate the compiler implicitly adds an initializer, and so it is not possible to jump over such a declaration:

    class A {
    public:
      A ();
    };
    
    switch (i)  // Error - jumping over initialization of 'A'
    {
       case 0:
         A j;   // Compiler implicitly calls default constructor
         break;
       case 1:
         break;
    }
    

    This limitation is not limited to the switch statement. It is also an error to use 'goto' to jump over an initialization:

    goto LABEL;    // Error jumping over initialization
    int j = 0; 
    LABEL:
      ;
    

    A bit of trivia is that this is a difference between C++ and C. In C, it is not an error to jump over the initialization.

    As others have mentioned, the solution is to add a nested block so that the lifetime of the variable is limited to the individual case label.

    0 讨论(0)
  • 2020-11-21 06:06

    The whole switch statement is in the same scope. To get around it, do this:

    switch (val)
    {
        case VAL:
        {
            // This **will** work
            int newVal = 42;
        }
        break;
    
        case ANOTHER_VAL:
          ...
        break;
    }
    

    Note the brackets.

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