为什么" case :: LABEL:"用g ++编译?

时间:2016-01-06 14:12:53

标签: c++ gcc g++

我很惊讶地发现g ++(4.9)正在编译这个(而gcc不会):

#include <stdio.h>

enum
{
    ONE   = 1,
    TWO   = 2,
    THREE = 3
};

int main(int argc, char* argv[])
{
    int sw = 2;

    switch (sw)
    {
    case::ONE:
    {
        printf("1\n");
        break;
    }

    case::TWO:
    {
        printf("2\n");
        break;
    }

    case::THREE:
    {
        printf("3\n");
        break;
    }

    default:
    {
        printf("default\n");
    }
    }
}

g ++预处理器如何能够分离&#34; case&#34;来自&#34; :: ONE:&#34;?

4 个答案:

答案 0 :(得分:4)

  

g ++预处理器如何能够分离&#34; case&#34;来自&#34; :: ONE:&#34;?

它不是预处理器,而只是编译器,它解释::以引用全局命名空间。

案例标签将被解析为

case :: THREE :

并且完全没问题,因为您的enum值出现在全局命名空间(::)中。

答案 1 :(得分:3)

它不是预处理器。 C编译器(其标记化器)将其视为:

case :: ONE

在c ++中没问题。 ::运算符表示根名称空间。 C没有这样的事情。

答案 2 :(得分:0)

你有一个简单的枚举,而不是一个范围的枚举(参见:enum class)。普通枚举位于根范围内,因此您可以编写::ONE

使用作用域枚举,您可以执行以下操作:

enum class Scoped { FIRST, LAST = 9};
//...
case Scoped::FIRST : //...

即使您不在case关键字和枚举器之间留下空格,g ++中的标记化程序(因为这是一个C ++功能)也可以解决。

答案 3 :(得分:0)

在编译过程的lexical analysis阶段,程序文件中的字符流将转换为标记。这里使用的一种流行算法是maximal munch,其中最长匹配的合法令牌被视为预期令牌。在此示例中,它将case::ONE:分为case::ONE:

还有一些缺点:x = y/*z是一个错误,因为/*是最长的匹配法律令牌,而用户可能想说x = y / *z。您可以找到许多这样的奇怪示例,其中几个是herehere