枚举对象设置为不等于其各自枚举常量的值

Vil*_*ray 6 c enums c99 language-lawyer

如果将枚举对象设置为不等于其任何相应枚举常量的值,则枚举对象具有什么值?

请考虑以下代码:

enum foobar{
    FOO = 1,
    BAR = 5
};

enum foobar baz = 5;
enum foobar qux = 42;
Run Code Online (Sandbox Code Playgroud)

变量baz设置为整数值5,而变量qux设置为整数值42.

我怀疑该变量baz将保留该值BAR,但我不确定该变量qux.没有为枚举常量赋值42,那么当enum foobar变量设置为这样的值时会发生什么?

是C99的标准明确患得患失?

das*_*ght 6

变量qux不会保留任何enums值.它的值将等于编译器选择表示的基础类型中的42 foobar,这是实现定义的.当值为42,这不会产生问题,但是当常量不适合编译器为枚举选择的类型时,它可能会成为一个问题.

编译器允许赋值除enum常量之外的原因之一是支持"flag"枚举,当期望常量按位运算组合时:

enum foobar {
    foo = 1
,   bar = 2
,   baz = 4
} test = (foo | baz);
Run Code Online (Sandbox Code Playgroud)

test上面的变量保存值5,它不对应于任何enum常量.


Sha*_*our 2

C99标准草案似乎并没有限制枚举器仅接受其成员的值,但它确实规定枚举器基础类型应能够表示其所有成员的值。6.7.2.2 枚举说明符部分对此进行了介绍:

每个枚举类型应与 char、有符号整数类型或无符号整数类型兼容。类型的选择是实现定义的,110),但应能够表示枚举的所有成员的值。

因此,如果您使用的值大于成员定义的值,您将依赖于实现定义的行为。在有符号整数溢出的情况下,会导致未定义的行为,如下5所示:

如果在计算表达式期间出现异常情况(即,如果结果未在数学上定义或不在其类型的可表示值范围内),则行为未定义。

通常,当枚举用于表示位字段时,我们会看到枚举被分配的值超出了其成员指定的值。

  • @ShafikYaghmour 没有未定义的行为,因为如果值不能适合有符号整数类型,C 表示转换是根据 6.3.1.3p3 实现定义的。 (2认同)
  • 在这种情况下,任何枚举数的最大值为 5。最窄可能的兼容整数类型的上限至少为 127。因此,将 -127 到 +127 之间的任何值分配给“enum foobar”对象是明确定义的。 (2认同)
  • @KeithThompson严格来说它不是UB(例如编译器无法停止翻译),即使我同意C委员会的Seebs:*从编写可移植代码的人的角度来看,这个定义非常接近“行为未定义”,因为我无法预测我会得到什么值,或者我是否会得到一个值。* (2认同)