c++variablesinitializationswitch-statement

Why can we declare an uninitialized variable in the case of a switch?


int i;
i = 2;
switch(i)
{
    case 1: 
        int k;
        break;
    case 2:
        k = 1;
        cout << k << endl;
        break;
}

I don't know why the code above works.

Here, we can never go into case 1 but why we can use k in case 2?


Solution

  • There are actually 2 questions:

    1. Why can I declare a variable after case label?

    It's because in C++ label has to be in form:

    N3337 6.1/1

    labeled-statement:

    ...

    • attribute-specifier-seqopt case constant-expression : statement

    ...

    And in C++ declaration statement is also considered as statement (as opposed to C):

    N3337 6/1:

    statement:

    ...

    • declaration-statement

    ...

    2. Why can I jump over variable declaration and then use it?

    Because: N3337 6.7/3

    It is possible to transfer into a block, but not in a way that bypasses declarations with initialization. A program that jumps (The transfer from the condition of a switch statement to a case label is considered a jump in this respect.)

    from a point where a variable with automatic storage duration is not in scope to a point where it is in scope is ill-formed unless the variable has scalar type, class type with a trivial default constructor and a trivial destructor, a cv-qualified version of one of these types, or an array of one of the preceding types and is declared without an initializer (8.5).

    Since k is of scalar type, and is not initialized at point of declaration jumping over it's declaration is possible. This is semantically equivalent:

    goto label;
    
    int x;
    
    label:
    cout << x << endl;
    

    However this wouldn't work if x was initialized at point of declaration:

     goto label;
    
        int x = 58; //error, jumping over declaration with initialization
    
        label:
        cout << x << endl;