如果枚举不能装入无符号整型,会发生什么情况?

What happens if an enum cannot fit into an unsigned integral type?

本文关键字:什么情况 整型 枚举 不能 装入 无符号 如果      更新时间:2023-10-16

正如Bathsheba所要求的,并作为"如果enum不能适合整型会发生什么?"的后续问题。:

假定enum定义如下:

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 output

//compilation failed

这是一个非常有趣的问题。简单的答案是,这是字面上未定义的:标准没有说任何关于这种情况。

有一个更好的例子,考虑以下enum:

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

按标准:

dcl。enum) /:[…没有初始化式的枚举数定义前一个枚举数的值加1后得到的值赋给枚举数

因此,本例中foo::undefined的值为2 (true+1)。不能表示为bool .

是病态的吗?

,根据标准,它是完全有效的,只有非固定底层类型有不能表示所有枚举数值的限制:

dcl。enum]/7:对于底层类型不固定的枚举,[…]如果没有整型可以表示所有枚举数的值,则该枚举是病态的。

它没有说明固定的底层类型不能表示所有枚举数的值。

原题oopsundefined的值是多少?

It is undefined:标准没有说明这种情况

foo::undefined的可能取值:

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

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

初始化式(如undefined=2)和"隐式"初始化式(如True=true, undefined)的区别

按标准:

dcl。enum]/5:如果基础类型是固定的,则右括号之前的每个枚举数的类型都是基础类型,并且枚举数定义中的常量表达式应是基础类型的转换常量表达式。

换句话说:

 enum bar : bool { undefined=2 };

等价于

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

bar::undefined将是true。在"隐式"初始化式中,情况并非如此:本标准段落只说明初始化式,而不是"隐式"初始化式。

总结
    通过这种方式,具有固定底层类型enum可能具有不可表示的值。
  1. 标准未定义其值

根据问题和评论,这在GCC和clang中无效,但在MSVS-2015中有效(带有警告)。