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?
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 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.