Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 637
con-f-use Avatar asked Mar 11 '23 12:03

con-f-use


1 Answers

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 bla 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.)

like image 58
Keith Thompson Avatar answered Mar 19 '23 11:03

Keith Thompson