不一致的警告"从'const unsigned char'转换为'const float'需要缩小转换"

Pau*_*zak 8 c++ gcc gcc-warning visual-c++ c++11

Visual C++ 2017和gcc 5.4 在此代码段中产生但不是conversion from 'const unsigned char' to 'const float' requires a narrowing conversion警告:Line BLine A

#include <iostream>

int main() {
    const unsigned char p = 13;
    const float         q = p;  // Line A

    std::cout << q << '\n';

    const unsigned char c[3] = {0, 1, 255};
    const float         f[3] = {c[2], c[0], c[1]};  // Line B

    for (auto x:f)
        std::cout << x << '\n';
}
Run Code Online (Sandbox Code Playgroud)

这个警告有效吗?为什么Line B治疗不同于Line A

son*_*yao 5

警告是有效的,从C++ 11开始,在聚合初始化中禁止缩小转换 ; 但不适用于复制初始化(如前所述).

如果initializer子句是表达式,则根据copy-initialization允许隐式转换, except if they are narrowing (as in list-initialization) (since C++11).

在C++ 11之前,在聚合初始化中允许缩小转换,但不再允许它们.

list-initialization通过禁止以下内容来限制允许的隐式转换:

  • 从整数类型转换为浮点类型,除非源是一个常量表达式,其值可以精确地存储在目标类型中

BTW: c[0],c[1]c[2]不是常量表达式 ; 你可以将数组声明为constexpr,即constexpr unsigned char c[3] = {0, 1, 255};.然后应用异常,B行也可以正常工作.

  • @PaulJurczak当`x`是`const int []`?(/sf/ask/1323217941/)时,请参阅C++ 11中的[`x [0] == 1`常量表达式. (2认同)
  • @songyuanyao:编译器可以发出过多使用字母E的警告,但仍然符合要求.标准只要求编译器为格式良好的代码生成正确的二进制文件. (2认同)