【发布时间】:2019-11-02 01:59:33
【问题描述】:
在使用列表初始化构造变量时(如int x{ 5 };)the standard §8.5.4 说:
如果需要缩小转换 […] 来转换任何参数,则程序格式错误。 (7) 窄化转换是一种隐式转换 - (7.4) 从整数类型或无作用域枚举类型到不能表示原始类型的所有值的整数类型,除非源是常量表达式,其值在整数提升后将适合目标类型。
那么为什么会编译呢?
char c{ 'A' };
char x{ c + c };
提醒一下,c + c 产生 int
static_assert(std::is_same_v<decltype(c + c), int>, "");
所以编译器应该抱怨缩小转换肯定不是一个常量表达式。
有趣的是,正确地将 x 声明为 unsigned char 无法编译:
char c{ 'A' };
unsigned char x{ c + c };
从 'int' 到 'unsigned char' 的 C2397 转换需要缩小转换
就像引入一个临时的一样:
char c{ 'A' };
int sum{ c + c };
char x{ sum }; //C2397 conversion from 'int' to 'char' requires [...]
那么为什么第一个版本可以编译?我正在使用 Visual Studio Community 2017 版本 15.9.5 并使用 /wall 编译它,所有警告都是在 x64 调试版本中启用的错误。设置标准的 C++11、C++14 和 C++17 都可以编译。
我提交了错误报告here
【问题讨论】:
-
clang gives 错误,而 gcc 给出警告。
-
你使用什么编译标志?是否使用了
-Wall或-Wnarrowing? (或他们的视觉工作室等价物。) -
似乎 Biagio Festa 的答案是正确的,但存在视觉工作室错误。
标签: c++ visual-studio c++11 list-initialization