Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Variable definition inside switch statement

In the following code, why is the variable i not assigned the value 1?

#include <stdio.h>      

int main(void)
{   
    int val = 0;
    switch (val) {         
        int i = 1;   //i is defined here

        case 0:
            printf("value: %d\n", i);
            break;
        default:
            printf("value: %d\n", i);
            break;
    }
    return 0;
}

When I compile, I get a warning about i not being initialized despite int i = 1; that clearly initializes it

$ gcc -Wall test.c
warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
    printf("value %d\n", i);
    ^

If val = 0, then the output is 0.

If val = 1 or anything else, then the output is also 0.

Please explain to me why the variable i is declared but not defined inside the switch. The object whose identifier is i exists with automatic storage duration (within the block) but is never initialized. Why?

like image 814
sakthi Avatar asked Mar 08 '16 11:03

sakthi


People also ask

Can we define variable inside switch case?

Declaring a variable inside a switch block is fine. Declaring after a case guard is not.

What variables are used in a switch statement?

The variable used in a switch statement can only be integers, convertable integers (byte, short, char), strings and enums. You can have any number of case statements within a switch.

Why are variables not allowed to be used as the case values in a switch?

If the cases were allowed to contain variables, the compiler would have to emit code that first evaluates these expressions and then compares the switch value against more than one other value. If that was the case, a switch statement would be just a syntactically-sugarized version of a chain of if and else if .

Can we declare variable in switch case Javascript?

In C language, you cannot declare any variables inside 'case' statements.


1 Answers

According to the C standard (6.8 Statements and blocks), emphasis mine:

3 A block allows a set of declarations and statements to be grouped into one syntactic unit. The initializers of objects that have automatic storage duration, and the variable length array declarators of ordinary identifiers with block scope, are evaluated and the values are stored in the objects (including storing an indeterminate value in objects without an initializer) each time the declaration is reached in the order of execution, as if it were a statement, and within each declaration in the order that declarators appear.

And (6.8.4.2 The switch statement)

4 A switch statement causes control to jump to, into, or past the statement that is the switch body, depending on the value of a controlling expression, and on the presence of a default label and the values of any case labels on or in the switch body. A case or default label is accessible only within the closest enclosing switch statement.

Thus the initializer of variable i is never evaluated because the declaration

  switch (val) {         
      int i = 1;   //i is defined here
      //...

is not reached in the order of execution due to jumps to case labels and like any variable with the automatic storage duration has indeterminate value.

See also this normative example from 6.8.4.2/7:

EXAMPLE In the artificial program fragment

switch (expr) 
{ 
    int i = 4;
    f(i); 

case 0: 
    i = 17; /* falls through into default code */ 
default:
    printf("%d\n", i); 
}

the object whose identifier is i exists with automatic storage duration (within the block) but is never initialized, and thus if the controlling expression has a nonzero value, the call to the printf function will access an indeterminate value. Similarly, the call to the function f cannot be reached.

like image 194
Vlad from Moscow Avatar answered Sep 17 '22 01:09

Vlad from Moscow