Valid, but worthless syntax in switch-case?

abelenky picture abelenky · Jan 18, 2017 · Viewed 13.9k times · Source

Through a little typo, I accidentally found this construct:

int main(void) {
    char foo = 'c';

    switch(foo)
    {
        printf("Cant Touch This\n");   // This line is Unreachable

        case 'a': printf("A\n"); break;
        case 'b': printf("B\n"); break;
        case 'c': printf("C\n"); break;
        case 'd': printf("D\n"); break;
    }

    return 0;
}

It seems that the printf at the top of the switch statement is valid, but also completely unreachable.

I got a clean compile, without even a warning about unreachable code, but this seems pointless.

Should a compiler flag this as unreachable code?
Does this serve any purpose at all?

Answer

AlexD picture AlexD · Jan 18, 2017

Perhaps not the most useful, but not completely worthless. You may use it to declare a local variable available within switch scope.

switch (foo)
{
    int i;
case 0:
    i = 0;
    //....
case 1:
    i = 1;
    //....
}

The standard (N1579 6.8.4.2/7) has the following sample:

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.

P.S. BTW, the sample is not valid C++ code. In that case (N4140 6.7/3, emphasis mine):

A program that jumps90 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).


90) The transfer from the condition of a switch statement to a case label is considered a jump in this respect.

So replacing int i = 4; with int i; makes it a valid C++.