【问题标题】:Can an out-of-range enum conversion produce a value outside the underlying type?超出范围的枚举转换能否产生基础类型之外的值?
【发布时间】:2023-03-05 18:14:01
【问题描述】:

考虑以下几点:

#include <iostream>

enum class E : bool { A, B };

void foo(E e)
{
    switch(e)
    {
    case E::A: break;
    case E::B: break;
    default: std::cout << "aha\n";
    }
}

int main()
{
    foo( static_cast<E>(3) );
}

我的问题是:default 的情况可以触发,即这个程序产生输出吗?

N3936 中的棘手点似乎是 static_cast 在将超出范围的整数转换为枚举类型时的规范,[expr.static.cast]/10:

整数或枚举类型的值可以显式转换为枚举类型。如果原始值在枚举值范围内,则该值不变。否则,结果 值未指定(可能不在该范围内)

粗体文本没有明确表示该值必须仍在基础类型的范围内,但我想知道它是否有意这样做。

【问题讨论】:

  • 注意:我不打算将我的问题仅限于这个例子 - 如果可能的话,一个也涵盖非固定基础类型枚举的答案会很好
  • 这是CWG 1766的UB。
  • 是的,考虑到未定义的演员表,它可以。至少 VS2013 确实打印“啊哈”
  • 另见this question

标签: c++ language-lawyer c++14


【解决方案1】:

我认为 [expr.static.cast]/10 回答了这个问题。在当前的工作草案中,内容如下:

整数或枚举类型的值可以显式转换为完整的枚举类型。如果原始值在枚举值 (7.2) 的范围内,则该值不变。 否则,行为 未定义。

换句话说,您的程序具有未定义的行为,因为具有固定基础类型的枚举类型的范围(在您的情况下为:bool)是该类型的范围。

您的报价更改受到resolution of CWG1766 (issues link) 的影响;请注意,该问题被识别为缺陷(因此您应该忘记原始措辞)。

【讨论】:

    猜你喜欢
    • 2019-08-29
    • 2022-01-07
    • 2019-06-15
    • 2017-04-21
    • 2013-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多