用大括号从double初始化float

Gab*_*iel 8 c++ value-initialization c++11 list-initialization c++14

为什么编译器(clang,gcc)在执行此操作时没有警告缩小转换

float a{3.1231231241234123512354123512341235123541235};
float a = {double(3.1231231241234123512354123512341235123541235)}
Run Code Online (Sandbox Code Playgroud)

我期待一个警告,因为我使用大括号进行显式值初始化.按照这个答案链接它应该吐出一个错误.

汇编在这里

eer*_*ika 15

[dcl.init.list] /§7(标准草案)

缩小转换是隐式转换

...

  • 从long double到double或float,或从double到float,除非source是常量表达式,转换后的实际值在可以表示的值范围内(即使它不能精确表示),或者

...

两个表达式3.14159double(3.141)是常量表达式和值在该范围内的值所能表述通过float.因此,转换不会像标准所定义的那样缩小,并且不需要警告转换.


但是对于更长的输入,它也不会发出警告

确实如此,只要该值超出了可表示的值范围float.


son*_*yao 10

因为源是常量表达式并且在这些情况下不会发生溢出,所以不会触发缩小转换错误.

(强调我的)

从long double转换为double或者float并从double转换为float,除非source是常量表达式并且不会发生溢出

如果将它与double变量(即非常量表达式)或具有较大值的常量一起使用而导致过低,则将生成诊断消息.例如

double d = 3.14159;
float a {d}; // non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list
Run Code Online (Sandbox Code Playgroud)

编辑(更长输入)

因为即使值不能完全表示float,溢出仍然不会发生,那么它是允许的.

$ 8.6.4/7.2列表初始化 (强调我的)

从long double到double或float,或从double到float,除非source是常量表达式,转换后的实际值在可以表示的值范围内(即使它不能精确表示),或者