根据标准设置什么颜色?
引用C ++ 11和C ++ 14标准的报价:
[expr.static.cast] / 10
整数或枚举类型的值可以显式转换为枚举类型。如果原始值在枚举值(7.2)的范围内,则该值不变。否则,结果值将不确定(并且可能不在该范围内)。
我们来看一下枚举值的范围:[dcl.enum] / 7
对于基础类型固定的枚举,该枚举的值为基础类型的值。
在CWG 1766(C ++ 11,C ++ 14)之前
因此,对于data[0] == 100
,将指定结果值(*),并且不涉及未定义行为(UB)。更一般而言,当您从基础类型转换为枚举类型时,in中的任何值data[0]
都不会导致UB static_cast
。
在CWG 1766(C ++ 17)之后,
请参阅CWG缺陷1766。[expr.static.cast] p10段落得到了增强,因此如果将超出枚举可表示范围的值强制转换为枚举类型,则现在可以调用UB。这仍然不适用于问题中的场景,因为它data[0]
是枚举的基础类型(请参见上文)。
请注意,CWG 1766被认为是标准中的缺陷,因此编译器实施者可以将其应用于其C ++ 11和C ++ 14编译模式。
(*)char
至少必须为8位宽,但不必为unsigned
。可存储的最大值至少127
应符合C99标准的附录E。
比较[expr] / 4
如果在对表达式求值时,未在数学上定义结果或该类型的结果不在可表示值的范围内,则行为不确定。
在CWG 1766之前,转换积分类型->枚举类型会产生未指定的值。问题是:未指定的值是否可以超出其类型的可表示值?我相信答案是否定的 -如果答案是肯定的,那么您对有符号类型的操作所获得的保证在“此操作产生未指定的值”和“此操作具有未定义的行为”之间不会有任何区别。
因此,之前CWG 1766,甚至static_cast<Color>(10000)
会不调用UB; 但是在CWG 1766之后,它会调用UB。
现在,该switch
语句:
[stmt.switch] / 2
条件应为整数类型,枚举类型或类类型。[...]进行整体促销。
[conv.prom] / 4
可以将其基础类型为固定(7.2)的无作用域枚举类型的prvalue转换为其基础类型的prvalue。此外,如果可以将积分提升应用于其基础类型,则其基础类型固定的无范围枚举类型的prvalue也可以转换为提升的基础类型的prvalue。
注意:不带enum-base的作用域枚举的基础类型是int
。对于无作用域的枚举,其基础类型是实现定义的,但不得大于int
如果int
可以包含所有枚举器的值。
对于无范围的枚举,这使我们得出/ 1
以外的整数类型的prvalue bool
,char16_t
,char32_t
,或wchar_t
,其整数转换秩(4.13)小于的秩int
可以被转换成类型的prvalue int
如果int
可以表示源类型的所有值; 否则,可以将源prvalue转换为type的prvalue unsigned int
。
在无范围枚举的情况下,我们将在int
此处处理s。对于范围内的枚举(enum class
和enum struct
),不应用整数提升。无论如何,积分提升也不会导致UB,因为存储的值在基础类型的范围内和的范围内int
。
[stmt.switch] / 5
switch
执行该语句时,将评估其条件并将其与每种情况常量进行比较。如果大小写常量之一等于条件值,则将控制传递给匹配case
标签后的语句。如果没有case
常数与条件匹配,并且没有default
标签,则控制权传递到由default
标签标记的语句。
该default
标签应被击中。
注意:可以再看一下比较运算符,但是在引用的“比较”中未明确使用它。实际上,在我们的案例中,没有暗示会为有范围或无范围的枚举引入UB。
作为奖励,标准是否对此做了任何保证,但带有简单的枚举?
无论是否enum
是作用不作任何这里的区别。但是,底层类型是否固定确实会有所不同。完整的[decl.enum] / 7是:
对于基础类型固定的枚举,该枚举的值为基础类型的值。否则,对于枚举其中Ë 分钟是最小的枚举和Ë 最大值是最大的,枚举的值是值的范围b 分钟至b 最大值,定义如下:令K
是1
对于二的补码表示和0
用于一个人的补码或符号幅度表示。b max是大于或等于max(| e min | − K
,| e max |)且等于2的最小值M -1,其中M
是一个非负整数。如果 e min为非负值,则 b min为零,否则为 -(b max + )。K
让我们看一下以下枚举:
enum ColorUnfixed /* no fixed underlying type */
{
red = 0x1,
yellow = 0x2
}
请注意,我们无法将其定义为作用域枚举,因为所有作用域枚举都有固定的基础类型。
幸运的是,ColorUnfixed
最小的枚举数是red = 0x1
,因此max(| e min | − K
,| e max |)等于| e max |。无论如何是yellow = 0x2
。最小的值大于或等于2
,等于2 中号 - 1为正整数M
是3
(2 2 - 1)。(我认为目的是允许范围以1位为步长扩展。)因此,b max是3
,bmin是0
。
因此,100
将在的范围之外ColorUnfixed
,并且static_cast
会在CWG 1766之前产生未指定的值,在CWG 1766之后会产生未定义的行为。
char
,因此“如果原始值在枚举值(7.2)的范围内,则该值不变。” 适用。