views:

347

answers:

9
#include<stdio.h>

int main() {
    int a = 1;
    switch (a) {
            int b = 20;
        case 1:
        {
            printf("b is %d\n", b);
            break;
        }
        default:
        {
            printf("b is %d\n", b);
            break;
        }
    }
    return 0;
}
+29  A: 

Because the switch statement jumps to a relevant case, so the line int b = 20 will never be executed.

Rasmus Kaj
wow this guy went from like 21 reputation to 201 lol
Earlz
Congrats on hitting the rep cap on your first day here, Rasmus.
Chris Lutz
Thanks, Chris, and all who "upped"! :-)
Rasmus Kaj
A: 

The line

int b=20;

Is not executed before the switch is entered. You would have to move it above the switch statement to get 20 output.

Dave Swersky
+8  A: 

Your compiler should warn you about this. The initialization of 'b' is at the beginning of the switch statement, where it will never be executed -- execution will always flow directly from the switch statement header to the matching case label.

Jerry Coffin
Agreed. If it doesn't, add the -Wall flag. If it still doesn't read the compiler manual for the correct flag to enable warnings or get a better compiler (for example gcc).
Rasmus Kaj
yes, compiling with -Wall all the time is a very good habit.
devin
+2  A: 

It doesn't output "b = 20" because b is set inside the switch statement and this instruction is never executed. What you want is this:

int b = 20;
switch (a) {
    case 1:
    {
        printf("b is %d\n", b);
        break;
    }
    default:
    {
        printf("b is %d\n", b);
        break;
    }
}
schnaader
+2  A: 

Gcc throws a warning saying that b is uninitialized when you call the printf()

you have to move "int b = 20" before the switch()

wezzy
+2  A: 

Inside of a switch is a hidden goto statement. So basically what is happening is really

int a=1;
if(a==1){ //case 1
  goto case1;
}else{ //default
  goto default;
}
int b=20;
case1:....
Earlz
Inside of an "else" is a hidden goto statement, so basically what is happening is really... ;-)
Steve Jessop
Well I could have dropped to assembly and just did `cmp [a],1; je case1` but I figured that was overkill
Earlz
+2  A: 

Remember that case labels in switch statement are called "labels" for a reason: they are pretty much ordinary labels, just like the ones you can goto to. This is actually how switch works: it is just a structured version of goto that just jumps from switch to the appropriate label and continues execution from there. In your code you always jump over initialization of b. So, b never gets initialized.

AndreyT
+1  A: 

The code

int b = 20

is actually doing two things:

int b

and

b = 20

The compiler sets up a variable called b when it compiles the program. This is an automatic variable, which goes on the stack. But it does not assign it a value until the program execution reaches that point.

Before that point, it is unknown what value the variable has.

This would not be true for a global variable, or a static variable -- those are initialized when the program begins running.

Kevin Panko
how is this relevant? the problem is obviously the initialization is never reached because of it's placement in the switch
Earlz
To be fair, he surely just wanted to just say that "b" is still in scope (since it's a compile time thing), which he seem to say is the "int b" part, but just the assignment is not done. So, in other words, the line is not completely ignored.
Johannes Schaub - litb
The bottom line is, declaring a variable and initializing that variable happen at different times, even though the same line of code does both.
Kevin Panko
Aren't statics with block scope initialised the first time their definition is executed? Or is that only in C++?
Steve Jessop
In the above code, if "b" is made static, then the output is indeed 20. If you give it to a C++ compiler, it refuses to compile.
Kevin Panko
+1  A: 

Compiling with gcc (Using cygwin on Windows) gives a warning message -

warning: unreachable code at beginning of switch statement

and the output is undefined or garbage which clearly says that initialization portion of b is never executed and hence the undefined value.

Note: Question can be raised that if the code or line is unreachable, then why does not we get the error: 'b' undeclared.

The compiler checks for the syntax of the program (above checks if b is declared) and finds it correct (b is declared), although semantically/logically it is incorrect.

Probably in future the compilers may become even more smarter and will be able to detect these kind of errors

Devil Jin
@Devil Jin thanks. nice points there.
Amoeba