- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
考虑这个 C++11 代码:
enum class Color : char { red = 0x1, yellow = 0x2 }
// ...
char *data = ReadFile();
Color color = static_cast<Color>(data[0]);
switch (color) {
// ... red and yellow cases omitted
default:
// handle error
break;
}
最佳答案
What is color set to according to the standard?
A value of integral or enumeration type can be explicitly converted to an enumeration type. The value is unchanged if the original value is within the range of the enumeration values (7.2). Otherwise, the resulting value is unspecified (and might not be in that range).
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type.
data[0] == 100
,结果值被指定(*),并且没有
Undefined Behaviour (UB)涉及。更一般地,当您从基础类型转换为枚举类型时,
data[0]
中没有值。可能导致
static_cast
的 UB .
data[0]
是枚举的基础类型(见上文)。
char
要求至少为 8 位宽,但不要求为
unsigned
.可存储的最大值要求至少为
127
根据 C99 标准的附录 E。
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined.
static_cast<Color>(10000)
会
不是 调用UB;但在 CWG 1766 之后,它
调用UB。
switch
陈述:
The condition shall be of integral type, enumeration type, or class type. [...] Integral promotions are performed.
A prvalue of an unscoped enumeration type whose underlying type is fixed (7.2) can be converted to a prvalue of its underlying type. Moreover, if integral promotion can be applied to its underlying type, a prvalue of an unscoped enumeration type whose underlying type is fixed can also be converted to a prvalue of the promoted underlying type.
int
.对于无作用域枚举,底层类型是实现定义的,但不应大于
int
如果
int
可以包含所有枚举器的值。
A prvalue of an integer type other than
bool
,char16_t
,char32_t
, orwchar_t
whose integer conversion rank (4.13) is less than the rank ofint
can be converted to a prvalue of typeint
ifint
can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of typeunsigned int
.
int
在这里。对于
范围枚举(
enum class
和
enum struct
),不适用积分促销。无论如何,积分提升也不会导致 UB,因为存储的值在基础类型的范围内,并且在
int
的范围内。 .
When the
switch
statement is executed, its condition is evaluated and compared with each case constant. If one of the case constants is equal to the value of the condition, control is passed to the statement following the matchedcase
label. If nocase
constant matches the condition, and if there is adefault
label, control passes to the statement labeled by thedefault
label.
default
标签应该被击中。
As a bonus, does the standard make any guarantees as about this but with plain enum?
enum
is scoped 在这里没有任何区别。但是,基础类型是否固定确实有所不同。完整的 [decl.enum]/7 是:
For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. Otherwise, for an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values in the range bmin to bmax, defined as follows: Let
K
be1
for a two's complement representation and0
for a one's complement or sign-magnitude representation. bmax is the smallest value greater than or equal to max(|emin| −K
, |emax|) and equal to 2M − 1, whereM
is a non-negative integer. bmin is zero if emin is non-negative and −(bmax +K
) otherwise.
enum ColorUnfixed /* no fixed underlying type */
{
red = 0x1,
yellow = 0x2
}
ColorUnfixed
的最小枚举数是
red = 0x1
,所以 max(|emin| −
K
, |emax|) 等于 |emax|无论如何,这是
yellow = 0x2
.大于或等于
2
的最小值,对于正整数
M
等于 2M - 1是
3
(22 - 1)。 (我认为目的是允许范围以 1 位步长扩展。)因此 bmax 是
3
bmin 是
0
.
100
将超出
ColorUnfixed
的范围,以及
static_cast
将在 CWG 1766 之前产生未指定的值,在 CWG 1766 之后产生未定义的行为。
关于c++ - 如果您向枚举类 static_cast 无效值会发生什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18195312/
我是一名优秀的程序员,十分优秀!