0%

(Stack Overflow) Why can't variables be declared in a switch statement?

Question

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 them close to first use is obviously a good thing) but the following still won’t work:

1
2
3
4
5
6
7
8
9
10
switch (val)
{
case VAL:
// This won't work
int newVal = 42;
break;
case ANOTHER_VAL:
...
break;
}

The above gives me the following error (MSC):

initialization of ‘newVal’ is skipped by ‘case’ label

This seems to be a limitation in other languages too. Why is this such a problem?

Answer by Rob

This question is tagged as [C] and [C++] at the same time. The original code is indeed invalid in both C and C++, but for completely different unrelated reasons. I believe this important detail was missed (or obfuscated) by the existing answers.

  • In C++ this code is invalid because the case ANOTHER_VAL: label jumps into the scope of variable newVal bypassing its initialization. Jumps that bypass initialization of local objects are illegal in C++. This side of the issue is correctly addressed by most answers.

  • However, in C language bypassing variable initialization is not an error. Jumping into the scope of a variable over it initialization is legal in C. It simply means that the variable is left uninitialized. The original code does not compile in C for a completely different reason. Label case VAL: in the original code is attached to the declaration of variable newVal. In C language declarations are not statements. They cannot be labeled. And this is what causes the error when this code is interpreted as C code.

1
2
3
4
5
6
7
8
9
switch (val)
{
case VAL: /* <- C error is here */
int newVal = 42;
break;
case ANOTHER_VAL: /* <- C++ error is here */
...
break;
}

Adding an extra {} block fixes both C++ and C problems, even though these problems happen to be very different. On the C++ side it restricts the scope of newVal, making sure that case ANOTHER_VAL: no longer jumps into that scope, which eliminates the C++ issue. On the C side that extra {} introduces a compound statement, thus making the case VAL: label to apply to a statement, which eliminates the C issue.

  • In C case the problem can be easily solved without the {}. Just add an empty statement after the case VAL: label and the code will become valid

    1
    2
    3
    4
    5
    6
    7
    8
    9
    switch (val)
    {
    case VAL:; /* Now it works in C! */
    int newVal = 42;
    break;
    case ANOTHER_VAL:
    ...
    break;
    }

    Note that even though it is now valid from C point of view, it remains invalid from C++ point of view.

  • Symmetrically, in C++ case the the problem can be easily solved without the {}. Just remove the initializer from variable declaration and the code will become valid

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    switch (val)
    {
    case VAL:
    int newVal;
    newVal = 42;
    break;
    case ANOTHER_VAL: /* Now it works in C++! */
    ...
    break;
    }

    Note that even though it is now valid from C++ point of view, it remains invalid from C point of view.


Article link: http://xnerv.wang/why-cant-variables-be-declared-in-a-switch-statement/
Reprinted from: (StackOverflow) Why can’t variables be declared in a switch statement? (answered by AnT)