我很惊讶地发现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;?
答案 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
。您可以找到许多这样的奇怪示例,其中几个是here和here。