如果一个枚举无法适合一个无符号整型,会发生什么?

按照Bathsheba的要求,并作为“如果枚举不能整合到一个types中会发生什么?”的后续问题。 :

假设一个枚举定义如下:

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 

这是一个非常有趣的问题。 简单的答案是,这是从字面上来说是不确定的:标准没有对这种情况说什么。

为了有一个更好的例子,考虑这个enum

  enum foo : bool { True=true, undefined }; 

按照标准:

[ dcl.enum ] / 2 :[…]没有初始化器枚举器定义枚举器通过将一个枚举器的值加1而获得的值。

因此,在我们的例子中foo::undefined的值是2true+1 )。 这不能被表示为一个bool

它是不合格的吗?

,根据标准,这是完全有效的,只有没有固定的基础types有一个限制,不能够代表所有的枚举值:

[ dcl.enum ] / 7 :对于其基础types不固定的枚举,[…]如果没有整型可以表示所有的枚举值,则枚举是不合格的。

它没有提到一个固定的底层types ,它不能代表所有的枚举值。

什么是原始问题的oops的价值和undefined

这是不明确的 :标准没有对这种情况说任何东西。

foo::undefined可能值:

  • 最高可能值( true ): undefinedoops应该是基础types的最大值。
  • 可能的最低值( false ): 底层types的最小值。 注意:在有符号整数中,它不会与整数溢出(未定义行为)的当前行为相匹配。
  • 随机值(?):编译器会select一个值。

所有这些值的问题是,它可能会导致两个字段具有相同的值(例如foo::True == foo::undefined )。

初始值 (例如undefined=2 )和“隐式”初始值(例如True=true, undefined

按照标准:

[ dcl.enum ] / 5 :如果基础types是固定的,则在大括号之前的每个枚举器的types是底层types枚举器定义中的常量expression式应该是基础types的转换常量expression式。

换一种说法:

  enum bar : bool { undefined=2 }; 

相当于

  enum bar : bool { undefined=static_cast<bool>(2) }; 

然后bar::undefinedtrue 。 在“隐式”初始化器中,情况并非如此:这个标准段落只是说明了初始化器 ,而不是“隐式”初始化器。

概要

  1. 通过这种方式, 固定基础typesenum可能具有不可表示的值。
  2. 他们的价值是不确定的标准。

根据问题和意见,这在GCC和叮当中是无效的,但对MSVS-2015有效(有警告)。