【问题标题】:Narrowing conversion to bool warning in MSVC在 MSVC 中缩小到布尔警告的转换范围
【发布时间】:2019-02-12 20:19:24
【问题描述】:

编译这段代码时:

enum B: bool { T = true };
struct A { bool member; };

void foo(const B b = T)
{
    A a{b}; // warning here
}

void bar()
{
    const B b = T;
    A a{b};
}

MSVC 在foo 中发出警告:

警告 C4838:从“const B”到“bool”的转换需要缩小转换

但编译 bar 很好。

这是proof

这是编译器错误还是预期行为?

【问题讨论】:

  • 我的猜测是您遇到了list initialization 问题,它正在执行整数提升。根据我对 CPPReference 的阅读,这不是 UB 并且是允许的,但 MS 让您知道它在技术上是一种缩小转换。
  • 是否修复了将enum B 更改为enum class B 的警告?

标签: c++ visual-c++


【解决方案1】:

narrowing conversion的相关部分定义在C++17 [dcl.init.list]/7:

窄化转换是一种隐式转换:

  • [...]
  • 从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,其值在整数提升后将适合目标类型。

在您的代码中,B 是一个无范围的枚举,具有固定的基础类型 bool。在 [dcl.enum]/8 中它说:

对于底层类型固定的枚举,枚举的值就是底层类型的值

这意味着B 的唯一可能值是bool 的值,即truefalse。它不能保存其他值。

由于A::member 实际上可以代表B 的所有值,所以它不是缩小转换,所以警告是假的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-29
    • 1970-01-01
    • 1970-01-01
    • 2020-09-23
    • 2013-12-16
    • 1970-01-01
    • 2021-05-14
    相关资源
    最近更新 更多