用大括号从double初始化float

时间:2016-11-25 13:10:44

标签: c++ c++11 c++14 list-initialization value-initialization

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

float a{3.1231231241234123512354123512341235123541235};
float a = {double(3.1231231241234123512354123512341235123541235)}

我期待一个警告,因为我使用大括号进行显式值初始化。 在回答Link之后,它应该发出错误。

Compilation here

2 个答案:

答案 0 :(得分:15)

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

  

缩小转化是隐式转化

     

...

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

...

表达式3.14159double(3.141)都是常量表达式,值在float可表示的值范围内。因此,转换不是标准定义的缩小,并且不需要警告转换。

  

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

Sure it does,只要该值超出float所代表的值范围。

答案 1 :(得分:10)

因为源是常量表达式并且在这些情况下不会发生溢出,所以不会触发narrowing conversion错误。

(强调我的)

  

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

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

double d = 3.14159;
float a {d}; // non-constant-expression cannot be narrowed from type 'double' to 'float' in initializer list

编辑(用于更长时间的输入)

因为即使float无法准确表示该值,仍然不会发生溢出,那么它是允许的。

$8.6.4/7.2 List-initialization (强调我的)

  

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