Home > OS >  unusual switch statement label - why isn't this a syntax error?
unusual switch statement label - why isn't this a syntax error?

Time:11-20

I've inherited a very old ( 15 years old) C program currently running on AIX using IBM's xlc compiler. I came across a switch statement and I don't understand how this ever worked.

Below is a minimal example that shows the situation.

#include <iostream>
using namespace std;

int main()
{
        int i=5;

        switch( i ) {
                case 1:
                        cout << "case " << i << endl;
                        break;
                case 2:
                        cout << "case " << i << endl;
                        break;
                Otherwise:
                        cout << "case " << i << endl;
                        break;
        }
        cout << "bye\n";
}

I'm using GCC 7.3.1 on Amazon Linux 2. The program compiles fine and shows this output is:

bye

If I add "-Wall", then it tells me the following:

minex.C: In function ‘int main()’:
minex.C:15:3: warning: label ‘Otherwise’ defined but not used [-Wunused-label]
   Otherwise:
   ^~~~~~~~~

Questions:

  1. Why isn't this a syntax error?

  2. Don't the case labels have to follow the form "case n:" where n is an integer expression or "default:" (or a constant String expression, but that doesn't seem relevant here?

  3. Can someone please point me to a reference that says this is supposed to be allowed?

CodePudding user response:

A label can occur on any statement. That the statement happens to be inside of a switch block doesn't matter. This label can be jumped to from anyplace inside the current function.

A case label or default can only appear inside of a switch, but that doesn't prevent other labels from appearing there as well.

Section 9.1 of the C 17 standard describes labeled statements:

1 A statement can be labeled.

labeled-statement:

attribute-specifier-seqopt identifier : statement

attribute-specifier-seqopt case constant-expression : statement

attribute-specifier-seqopt default : statement

The optional attribute-specifier-seq appertains to the label. An identifier label declares the identifier. The only use of an identifier label is as the target of a goto. The scope of a label is the function in which it appears. Labels shall not be redeclared within a function. A label can be used in a goto statement before its declaration. Labels have their own name space and do not interfere with other identifiers. [ Note: A label may have the same name as another declaration in the same scope or a template-parameter from an enclosing scope. Unqualified name lookup (6.4.1) ignores labels. — end note ]

2 Case labels and default labels shall occur only in switch statements

Note that there are restrictions on case and default but not other labels.

  • Related