clang enum溢出

使用-Wall -pedantic

#include  #include  int main(void) { enum x { a, max = INT_MAX, out_1 }; enum y { b, out_2 = INT_MAX + 1 }; printf("%d %d\n", out_1, out_2); return 0; } 

铿锵回归

 demo.c:9:3: warning: overflow in enumeration value out_1 ^ 

正如您所看到的,编译器没有警告out_2溢出,他的值在编译时是未知的?

在第一个实例中,编译器本身正在尝试选择导致溢出的整数,因此警告您。 它可能会产生INT_MIN 。 该标准允许signed int任何值为枚举常量(参见底部)。

在第二个中,表达式(INT_MAX + 1)在分配给out_2之前计算。 这里表达式中的溢出产生了允许的结果,但这是未定义的行为。 然后将有效结果存储在枚举中,这就是不产生第一个错误的原因。

clang(3.2)也不会对此发出警告,这实际上是相同的:

 int a = INT_MAX + 1; 

在这方面,clang不符合C标准,因为这是不明确的。

相比之下,gcc的输出完全清楚了:

 In function 'main': 9:9: error: overflow in enumeration values 13:25: warning: integer overflow in expression [-Woverflow] 

英特尔编译器忽略枚举溢出,但警告整数溢出:

 enum.c(13): warning #61: integer operation result is out of range out_2 = INT_MAX + 1 ^ 

作为参考,从C99标准6.7.7.2.2开始,“定义枚举常量值的表达式应该是一个整数常量表达式,其值可以表示为int ; .3,”枚举器列表中的标识符是声明为具有int类型的常量,并且可以出现在允许的任何地方。“即枚举常量可以是任何int值,并且具有int类型。定义的枚举变量的结果类型可以是charintunsigned int ,as只要它允许枚举中的所有可能的常量。因此,示例中的两个enums都是未定义的,因为它们都需要整数溢出。第一个显然是非法的。

ISO C将整数指定为枚举值。

如果您的编译器允许它(以及GCC和Clang),那么INT_MIN是一个非常好的值。

如果编译器不允许指定的索引,则需要发出错误

明确请求的INT_MIN正常但INT_MAX前任的自动增加值发出警告的原因是该标准需要+1行为。