不寻常的 switch 语句标签 - 为什么这不是语法错误?

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

我继承了一个非常古老(+15 岁)的 C++ 程序,目前 运行 在 AIX 上使用 IBM 的 xlc 编译器。我遇到了一个 switch 语句,但我不明白它是如何工作的。

下面是一个显示情况的最小示例。

#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";
}

我在亚马逊上使用 GCC 7.3.1 Linux 2. 程序编译正常并显示此输出为:

bye

如果我添加“-Wall”,它会告诉我以下内容:

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

问题:

  1. 为什么这不是语法错误?

  2. 案例标签是否必须遵循“案例 n:”的形式,其中 n 是 整数表达式或“默认值:”(或常量字符串表达式,但这在这里似乎不相关?

  3. 谁能给我指出一个参考资料说这是 应该允许吗?

标签可以出现在任何语句中。该语句恰好位于 switch 块内并不重要。这个标签可以从当前函数内的任何地方跳转到。

case 标签或 default 只能出现在 switch 内,但这并不妨碍其他标签也出现在那里。

C++17 standard 的第 9.1 节描述了带标签的语句:

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

请注意,casedefault 有限制,但其他标签没有限制。