带大括号的 double 浮点初始化

float initialization from double with braces

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

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

我预计会收到警告,因为我使用大括号进行了显式值初始化。 按照这个答案 Link 它应该吐出一个错误。

Compilation here

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

(强调我的)

conversion from a long double to double or to float and conversion from double to float, except where the source is a constant expression and overflow does not occur

如果将它与 double 变量(即非常量表达式)或具有大值的常量一起使用会导致溢出,将生成诊断消息。例如

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

编辑(用于更长的输入)

因为即使float不能准确表示值,也不会发生溢出,所以是允许的。

.6.4/7.2 List-initialization (强调我的)

from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or

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

A narrowing conversion is an implicit conversion

...

  • from long double to double or float, or from double to float, except where the source is a constant expression and the actual value after conversion is within the range of values that can be represented (even if it cannot be represented exactly), or

...

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


but it does not give a warning also for longer inputs

Sure it does,只要该值在float.

可表示的值范围之外