【发布时间】:2017-01-29 23:20:08
【问题描述】:
根据Bathsheba 的要求和"What happens if an enum cannot fit into an integral type?" 的后续问题:
假设枚举定义如下:
enum foo : unsigned int
{
bar = UINT_MAX,
oops
};
oops 的值是否已定义?
MSVS2015编译:
warning C4340: 'oops': value wrapped from positive to negative value
warning C4309: 'initializing': truncation of constant value
warning C4369: 'oops': enumerator value '4294967296' cannot be represented as 'unsigned int', value is '0'
MSVS2015 输出:
bar = 4294967295
oops= 0
gcc 4.9.2 编译:
9 : note: in expansion of macro 'UINT_MAX'
bar = UINT_MAX,
^
10 : error: enumerator value 4294967296l is outside the range of underlying type 'unsigned int'
oops
^
Compilation failed
gcc 4.9.2 输出
//compilation failed
【问题讨论】:
-
似乎
int会是一个更有趣的问题,因为bar + 1的计算会导致UB。 -
@KerrekSB:这基本上是我对链接问题的回答的症结所在。
-
哼。 UINT_MAX + 1 显然是一个编译时可评估的常量表达式,但鉴于它不适合
unsigned,C++ 标准希望编译器选择 long long 作为枚举类型,但不能因为你已经强迫它成为unsigned。对我来说,这解释了编译器错误,甚至可能是答案。标准中的“如果基础类型是固定的,则可以将值转换为其提升的基础类型”中的行我认为也与它有关。 -
@Bathsheba 刚刚测试了一下,如果你不限制类型,你只会收到警告:coliru.stacked-crooked.com/a/a8306b64279b700c
-
[dcl.enum]/2 和 7 在这里似乎是相关的。 “如果枚举器的初始化值不能由底层类型表示,则程序格式错误。” 很有趣,但我不确定它是否适用。目前正试图在那里建立标准。
标签: c++ types enums language-lawyer