Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 789
James Avatar asked Jan 25 '23 05:01

James


1 Answers

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-seqoptcase constant-expression : statement

attribute-specifier-seqoptdefault : 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.

like image 96
dbush Avatar answered Jan 26 '23 18:01

dbush