本文介绍了如果枚举不能适合无符号整型类型,会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据的要求,作为:



由于枚举定义如下:

 枚举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




  • 最高价值( 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 。在一个隐式初始化器中,不一定是这样的:本标准段落仅说明了初始化程序,而不是关于隐式初始化程序。



摘要




  1. 以这种方式,可以使用枚举

  2. 他们的价值不符合标准。

根据问题和意见,这在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.

Is it ill-formed?

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.

What is the value of original question's oops and undefined?

It is undefined: the standard doesn't say anything about this case.

Possible values for foo::undefined:

  • Highest possible value (true): undefined and oops should be underlying type's maximum value.
  • Lowest possible value (false): the underlying type's minimum value. Note: In signed integers, it would not match the current behavior for Integer overflow (undefined behavior).
  • Random value (?): the compiler will choose an value.

The problem with all of these values is that it may result two fields with the same value (e.g. foo::True == foo::undefined).

The difference between initializer (e.g. 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.

Summary

  1. With this way, it is possible for an enum with a fixed-underlying-type to have unrepresentable values.
  2. Their value is undefined by the standard.

According to the question and comments, this is not valid in GCC and clang but valid for MSVS-2015 (with a warning).

这篇关于如果枚举不能适合无符号整型类型,会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-30 15:29