Pav*_*kin 25 c enums language-lawyer
一个简单的问题:enum { a } e = 1;有效吗?
换句话说:分配一个不存在于枚举常量值集中的值是否会导致定义明确的行为?
演示:
$ gcc t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>
$ clang t0.c -std=c11 -pedantic -Wall -Wextra -c
<nothing>
$ icc t0.c -std=c11 -pedantic -Wall -Wextra -c
t0.c(1): warning #188: enumerated type mixed with another type
# note: the same warning for enum { a } e = 0;
$ cl t0.c /std:c11 /Za /c
<nothing>
Run Code Online (Sandbox Code Playgroud)
kod*_*der 31
来自6.7.2.2中的C18标准:
每个枚举类型应与 char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够表示枚举的所有成员的值。
所以“是”enum { a } e = 1;是有效的。e是“整数”类型,因此它可以采用 value 1。不作为枚举值出现这一事实1没有问题。枚举成员只为一些可能的值提供方便的标识符。
这在 C 中有效,例如202x 工作草案:
6.7.2.2/4每个枚举类型应与char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,但应能够表示枚举所有成员的值
特别是由于“兼容类型”的要求:
6.2.7/1如果两个类型的类型相同,则它们具有兼容类型。附加规则 [...]
虽然超出了本问答的范围(C 标签,而不是 C++),但值得注意的是,这不适用于 C++,其中没有固定基础类型的“C 风格”无作用域枚举与 C 存在细微差别。有关C++案例的详细信息,请参见以下Q&A:
我在这个 C11 标准草案(就“约束”而言)中找不到任何禁止分配给像您这样的类型的参考(并且另一个答案enum中引用的 C18 标准使用基本相同的措辞)。
然而,C11 草案在附件 I \xe2\x80\x93 常见警告中确实提供了这一点:
\n\n\n1 \xc2\xa0\xc2\xa0\xc2\xa0 实现可能会在许多\n情况下生成警告,但这些情况均未指定为此国际\n标准的一部分。以下是一些较常见的情况。
\n
\n2
\n\xe2\x80\xa6
\n\xc2\xa0\xc2\xa0\xc2\xa0\xe2\x80\x94\xc2\xa0\xc2\xa0\xc2\xa0 一个值被赋予一个对象枚举类型,而不是通过分配作为该类型成员的枚举常量、具有相同类型的枚举对象、或返回相同枚举类型的函数的值 (6.7.2.2) 。
但是,建议的警告同样适用于像 这样的赋值enum { a } e = 0;,其中RHS 的值对应于有效的枚举常量,但它实际上既不是该类型的枚举常量,也不是该枚举类型的对象。