con-f-use con-f-use - 4 months ago 20
C Question

Declarations in switch statement

Consider this C-code, where

foo
is an
int
:

switch(foo){
case 1: {
int bla = 255;
case 2:
printf("case12 %d\n", bla);
break;
case 3:
printf("case3 %d\n", bla);
}
};


For different values of
foo
the code gives the following output:

case12 255 # foo=1
case12 255 # foo=2
case3 0 # foo=3


I have a problem understanding
foo=3
. The line that declares
bla
and defines its value should not execute, when
foo=3
. The switch statement should jump right to the label for
case 3:
. Yet there is no warning, so
bla
seems to have been declared at least. It might be used uninitialized and its value just happens to be
0
, though. Can you explain, what's happening in "case 3", and why this is legal C-code?

Answer

A switch statement is essentially a computed goto. The case labels can appear anywhere within the (usually compound) statement controlled by the switch, even within nested blocks.

The declaration int bla = 255; creates an int object blah` whose lifetime is the execution of the enclosing block and whose name is visible from the point of its declaration to the end of the block.

If the switch statement causes control to jump to the case 2: or case 3: label, it jumps into the scope of bla but jumps past its initialization. The value of bla is then garbage (not random, not necessarily 0) and in fact trying to refer to its value has undefined behavior.

You can do the same thing with a goto statement

Don't do that.

(For gcc, you'll get a warning if you compile with -Wall, or -Wextra, or -Wmaybe-uninitialized.)

(For another abuse of the switch statement, see Duff's Device.)