Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does switch(0) not result in a warning while if(0) does?

Given this code:

#include <stdio.h>

int main( int argc, char** argv )
{
    switch (0) { 
        case 1: printf("1"); 
        case 2: printf("2"); 
        default:
            printf("default");
            break; 
    }
    return 0;
}

I'd expect that the compiler would tell me something about either conditional expression is constant (switch (0) while VS2012 issues this warning for an if(0)) or unreachable code (case 1, case 2).

However, neither on ideone nor on Visual Studio 2012 nor on recent GCCs I receive anything like that.

Why don't even decent compilers complain here?

like image 772
eckes Avatar asked Jan 07 '23 02:01

eckes


2 Answers

I just tried it on CLANG with extended warning turned on and received the following warning:

enter image description here

Referring to (oddly enough) only the the first of the two lines in the switch that will never be executed:

   case 1: printf("1"); 
like image 104
ryyker Avatar answered Jan 18 '23 22:01

ryyker


From the C 2011 standard:

5.1.1.3 Diagnostics

1     A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) if a preprocessing translation unit or translation unit contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.9)
9) The intent is that an implementation should identify the nature of, and where possible localize, each violation. Of course, an implementation is free to produce any number of diagnostics as long as a valid program is still correctly translated. It may also successfully translate an invalid program.

Emphasis added.

So, a diagnostic is required if using a constant expression in a switch or if control expression is a constraint violation...

6.8.4.1 The if statement

Constraints

1     The controlling expression of an if statement shall have scalar type.
...
6.8.4.2 The switch statement

Constraints

1  The controlling expression of a switch statement shall have integer type.

2     If a switch statement has an associated case or default label within the scope of an identifier with a variably modified type, the entire switch statement shall be within the scope of that identifier.154)

3     The expression of each case label shall be an integer constant expression and no two of the case constant expressions in the same switch statement shall have the same value after conversion. There may be at most one default label in a switch statement. (Any enclosed switch statement may have a default label or case constant expressions with values that duplicate case constant expressions in the enclosing switch statement.)
154) That is, the declaration either precedes the switch statement, or it follows the last case or default label associated with the switch that is in the block containing the declaration.

...which it isn't.

This is basically a quality of implementation issue; the implementation may issue a diagnostic for using a constant expression in an if or switch statement, but it doesn't have to. if( 0 ) and switch( 0 ) may strike most of us as being hinky, but the implementation is not required to issue any diagnostics over them.

like image 37
John Bode Avatar answered Jan 18 '23 21:01

John Bode