The problem is that variables declared in one case
are still visible in the subsequent case
s unless an explicit { }
block is used, but they will not be initialized because the initialization code belongs to another case
.
In the following code, if foo
equals 1, everything is ok, but if it equals 2, we’ll accidentally use the i
variable which does exist but probably contains garbage.
switch(foo) { case 1: int i = 42; // i exists all the way to the end of the switch dostuff(i); break; case 2: dostuff(i*2); // i is *also* in scope here, but is not initialized! }
Wrapping the case in an explicit block solves the problem:
switch(foo) { case 1: { int i = 42; // i only exists within the { } dostuff(i); break; } case 2: dostuff(123); // Now you cannot use i accidentally }
Edit
To further elaborate, switch
statements are just a particularly fancy kind of a goto
. Here’s an analoguous piece of code exhibiting the same issue but using a goto
instead of a switch
:
int main() { if(rand() % 2) // Toss a coin goto end; int i = 42; end: // We either skipped the declaration of i or not, // but either way the variable i exists here, because // variable scopes are resolved at compile time. // Whether the *initialization* code was run, though, // depends on whether rand returned 0 or 1. std::cout << i; }