根据标准设置什么颜色?
引用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)的范围内,则该值不变。” 适用。