枚举转换和未定义行为
Enumeration conversion and undefined behavior
A value of integer or enumeration type can be converted to any
complete enumeration type.
- If the underlying type is not fixed, the
behavior is undefined if the value of expression is out of range (the
range is all values possible for the smallest bit field large enough
to hold all enumerators of the target enumeration).
我这里有两个问题:
如何无法修复枚举的基础类型。考虑这个例子:
enum A : int { i = -1, b = 'c' };
无论枚举值的类型如何,enum A
的基础类型是否固定?无论枚举值的类型如何,基础类型的固定是否由指定类型决定?例如这个枚举是固定的 enum B { b, c }
?
如何确定枚举的范围。考虑这个例子:
enum N { c = 'A', hex = 0x64 };
enum N
的范围是65到100吗?因此,以下强制转换中的行为未定义:
static_cast<N>(64) // UB?
static_cast<N>(101) // UB?
我写这篇文章的重点是如何阅读cppreference.com。 (这可能会让我看起来更像是在回答一个问题,而不是超出限制。)
How the underlying type of an enum cannot be fixed.
这是枚举类型的问题。因此,如果答案不在当前页面上,那么下一个要查找的地方就是
enumeration type。
方便的是,在您 link 访问的页面上,短语“枚举类型”是 link 的,因此您不必搜索;只需单击 link.
进入 enumeration type 页面后,您对“固定”感兴趣。所以为“固定”做一个find-in-page(ctrl-f
)。
第一次出现的“fixed”高度暗示了它的含义,而第二次和第三次出现在此上下文中定义了该术语。基础类型为 not fixed 的无作用域枚举类型的定义看起来像该部分中的表格 (1)
enum A { i = -1, b = 'c' };
而基础类型 固定的无作用域枚举类型的定义 看起来像该部分中的形式 (2)
enum A : int { i = -1, b = 'c' };
如果你指定底层类型,那么底层类型就是你指定的;它是固定的。如果你没有指定底层类型,那么底层类型就是编译器决定使用的任何类型;它不是预先确定的(即不固定)。
How I can determine the range of an enumeration
这是在你的报价中给出的:
the range is all values possible for the smallest bit field large enough to hold all enumerators of the target enumeration
说了很多话,但一次只说一段。让我们用你的例子:
enum N { c = 'A', hex = 0x64 };
- 该范围是最小位域的所有可能值,其大小足以容纳目标枚举的所有枚举数。
- 范围是最小位域的所有可能值,大到足以容纳
N
的所有枚举数。
- 该范围是足以容纳
'A'
和 0x64
的最小位域的所有可能值。
- 该范围是足以容纳
65
和 100
的最小位域的所有可能值。
- 该范围是最小位字段的所有可能值,其大小足以容纳可以用 7 位(无符号)表示的值。
- 范围是长度为 7 的位字段的所有可能值。
- 范围是 0 到 127。
虽然编译器在选择基础类型方面有一些回旋余地,但基础类型必须能够表示所有枚举数。无论选择什么基础类型,它都将由位组成,并且至少与定义中的“最小位域”一样大。枚举的范围由无论选择何种基础类型都可表示的值组成。此范围之外的值可能适合基础类型,但也可能不适合。因此,它们是否可以转换是不确定的。
A value of integer or enumeration type can be converted to any complete enumeration type.
- If the underlying type is not fixed, the behavior is undefined if the value of expression is out of range (the range is all values possible for the smallest bit field large enough to hold all enumerators of the target enumeration).
我这里有两个问题:
如何无法修复枚举的基础类型。考虑这个例子:
enum A : int { i = -1, b = 'c' };
无论枚举值的类型如何,
enum A
的基础类型是否固定?无论枚举值的类型如何,基础类型的固定是否由指定类型决定?例如这个枚举是固定的enum B { b, c }
?如何确定枚举的范围。考虑这个例子:
enum N { c = 'A', hex = 0x64 };
enum N
的范围是65到100吗?因此,以下强制转换中的行为未定义:static_cast<N>(64) // UB?
static_cast<N>(101) // UB?
我写这篇文章的重点是如何阅读cppreference.com。 (这可能会让我看起来更像是在回答一个问题,而不是超出限制。)
How the underlying type of an enum cannot be fixed.
这是枚举类型的问题。因此,如果答案不在当前页面上,那么下一个要查找的地方就是 enumeration type。 方便的是,在您 link 访问的页面上,短语“枚举类型”是 link 的,因此您不必搜索;只需单击 link.
进入 enumeration type 页面后,您对“固定”感兴趣。所以为“固定”做一个find-in-page(ctrl-f
)。
第一次出现的“fixed”高度暗示了它的含义,而第二次和第三次出现在此上下文中定义了该术语。基础类型为 not fixed 的无作用域枚举类型的定义看起来像该部分中的表格 (1)
enum A { i = -1, b = 'c' };
而基础类型 固定的无作用域枚举类型的定义 看起来像该部分中的形式 (2)
enum A : int { i = -1, b = 'c' };
如果你指定底层类型,那么底层类型就是你指定的;它是固定的。如果你没有指定底层类型,那么底层类型就是编译器决定使用的任何类型;它不是预先确定的(即不固定)。
How I can determine the range of an enumeration
这是在你的报价中给出的:
the range is all values possible for the smallest bit field large enough to hold all enumerators of the target enumeration
说了很多话,但一次只说一段。让我们用你的例子:
enum N { c = 'A', hex = 0x64 };
- 该范围是最小位域的所有可能值,其大小足以容纳目标枚举的所有枚举数。
- 范围是最小位域的所有可能值,大到足以容纳
N
的所有枚举数。 - 该范围是足以容纳
'A'
和0x64
的最小位域的所有可能值。 - 该范围是足以容纳
65
和100
的最小位域的所有可能值。 - 该范围是最小位字段的所有可能值,其大小足以容纳可以用 7 位(无符号)表示的值。
- 范围是长度为 7 的位字段的所有可能值。
- 范围是 0 到 127。
虽然编译器在选择基础类型方面有一些回旋余地,但基础类型必须能够表示所有枚举数。无论选择什么基础类型,它都将由位组成,并且至少与定义中的“最小位域”一样大。枚举的范围由无论选择何种基础类型都可表示的值组成。此范围之外的值可能适合基础类型,但也可能不适合。因此,它们是否可以转换是不确定的。