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
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.
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;
}
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;"
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.
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.
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.