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:
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?
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;"
You can't do this, because
case
labels are actually just entry points into the containing block.This is most clearly illustrated by Duff's device. Here's some code from Wikipedia:
Notice how the
case
labels totally ignore the block boundaries. Yes, this is evil. But this is why your code example doesn't work. Jumping to acase
label is the same as usinggoto
, so you aren't allowed to jump over a local variable with a constructor.As several other posters have indicated, you need to put in a block of your own:
It appears that anonymous objects can be declared or created in a switch case statement for the reason that they cannot be referenced and as such cannot fall through to the next case. Consider this example compiles on GCC 4.5.3 and Visual Studio 2008 (might be a compliance issue tho' so experts please weigh in)
A
switch
block isn't the same as a succession ofif/else if
blocks. I'm surprised no other answer explains it clearly.Consider this
switch
statement :It may be surprising, but the compiler will not see it as a simple
if/else if
. It will produce the following code :The
case
statements are converted into labels and then called withgoto
. The brackets create a new scope and it is easy to see now why you can't declare two variables with the same name within aswitch
block.It may look weird, but it is necessary to support fallthrough (that is, not using
break
to let execution continue to the nextcase
).C++ Standard has: It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps from a point where a local variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has POD type (3.9) and is declared without an initializer (8.5).
The code to illustrate this rule:
The code to show the initializer effect:
The whole switch statement is in the same scope. To get around it, do this:
Note the brackets.