根据的要求,作为:
由于枚举定义如下:
枚举foo:unsigned int
{
bar = UINT_MAX,
oops
};
是否定义了 oops
的值
MSVS2015编译:
警告C4340:'oops':从正值转换为负值的值
警告C4309:'初始化':截断常量值
警告C4369:'oops':枚举值' 4294967296'不能表示为'unsigned int',值为'0'
MSVS2015输出: p>
bar = 4294967295
oops = 0
gcc 4.9.2编译:
9:注意:扩展宏'UINT_MAX'
bar = UINT_MAX,
^
10:错误:枚举值4294967296l在底层类型unsigned int的范围之外
oops
^
编译失败
gcc 4.9.2输出
//编译失败
解决方案
这是一个非常有趣的问题。简单的答案是这个字面上没有定义:标准对这种情况没有任何意义。要获得更好的例子,请考虑这个枚举
:
枚举foo:bool {True = true,undefined};
根据标准:
它对于不能代表所有枚举器值的固定基础类型没有说明。
oops
和未定义
?它是未定义:该标准对此没有任何意见。
foo :: undefined $ c的可能值$ c>:
true
): undefined
和 oops
应该是>底层类型的最大值 false
):底层类型的最小值。注意:在有符号整数中,它不匹配整数溢出(未定义的行为)的当前行为。所有这些值的问题是它可能会导致两个值相同的字段(例如 foo :: True == foo :: undefined
)。
undefined = 2
)和隐式初始化器(例如 True = true,undefined
)符合标准:
换句话说:
枚举吧:bool {undefined = 2};
相当于
枚举bar:bool {undefined = static_cast< bool>(2)};
然后 bar :: undefined
将真
。在一个隐式初始化器中,不一定是这样的:本标准段落仅说明了初始化程序,而不是关于隐式初始化程序。
枚举
根据问题和意见,这在GCC和俚语中无效,但对MSVS-2015有效(带有警告)。
As requested by Bathsheba and as a follow up question to "What happens if an enum cannot fit into an integral type?":
Asuming an enum is defined as follows :
enum foo : unsigned int
{
bar = UINT_MAX,
oops
};
Is the value of oops
defined or isn't it?
MSVS2015 compilation:
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 output:
bar = 4294967295
oops= 0
gcc 4.9.2 compilation:
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
解决方案 This is a very interesting question. The simple answer is that this is literally undefined: the standard doesn't say anything about this case.
To have a better example, consider this enum
:
enum foo : bool { True=true, undefined };
According to the standard:
Therefore, the value of foo::undefined
in our example is 2
(true+1
). Which can not be represented as a bool
.
No, according to the standard, it is perfectly valid, only not-fixed underlying type have a restriction about not being able to represent all of the enumerator values:
It says nothing about a fixed underlying type that can not represent all the enumerator values.
oops
and undefined
?It is undefined: the standard doesn't say anything about this case.
Possible values for foo::undefined
:
true
): undefined
and oops
should be underlying type's maximum value.false
): the underlying type's minimum value. Note: In signed integers, it would not match the current behavior for Integer overflow (undefined behavior).The problem with all of these values is that it may result two fields with the same value (e.g. foo::True == foo::undefined
).
undefined=2
) and "implicit" initializer (e.g. True=true, undefined
)According to the standard:
In other words:
enum bar : bool { undefined=2 };
is equivalent to
enum bar : bool { undefined=static_cast<bool>(2) };
And then bar::undefined
will be true
. In an "implicit" initializer, it would not be the case: this standard paragraph say it about only initializer, and not about "implicit" initializer.
enum
with a fixed-underlying-type to have unrepresentable values.According to the question and comments, this is not valid in GCC and clang but valid for MSVS-2015 (with a warning).
这篇关于如果枚举不能适合无符号整型类型,会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!