为什么 gcc 仅针对统一初始化警告缩小转换?

ks1*_*322 5 c++ compiler-warnings language-lawyer uniform-initialization c++11

我正在尝试将long类型变量转换为int带有uniform initialization和不带有它的类型变量。但是我只有在统一初始化时才会收到编译器警告。这是为什么?为什么gcc在这两种情况下都不发出警告?我也尝试过clang并得到了类似的结果。

这是代码

#include <iostream>

int main() {
    long l = 1;
    int i1 = l;
    int i2 = { l };

    std::cout << i1 << std::endl;
    std::cout << i2 << std::endl;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我得到的唯一警告

$ g++ -Wall -Wextra 1.cpp
1.cpp: In function ‘int main()’:
1.cpp:6:16: warning: narrowing conversion of ‘l’ from ‘long int’ to ‘int’ inside { } [-Wnarrowing]
   int i2 = { l };
Run Code Online (Sandbox Code Playgroud)

son*_*yao 5

因为标准规定,缩小转换限制仅针对列表初始化指定(自 C++11 起)。

列表初始化通过禁止以下内容来限制允许的隐式转换:

  • 从浮点类型到整数类型的转换
  • 从 long double 到 double 或到 float 的转换以及从 double 到 float 的转换,除非源是常量表达式并且不会发生溢出
  • 从整数类型到浮点类型的转换,除非源是常量表达式,其值可以精确地存储在目标类型中
  • 从整数或无范围枚举类型到不能表示原始值的所有值的整数类型的转换,除非源是常量表达式,其值可以精确地存储在目标类型中

对于其他初始化方法(使用括号或等号),不应用缩小转换限制规则(添加);因为这可能会破坏很多遗留代码。