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:
Why isn't this a syntax error?
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?
Can someone please point me to a reference that says this is supposed to be allowed?
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 agoto
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With