8

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

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

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

在这里编译

4

2 回答 2

15

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

缩小转换是隐式转换

...

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

...

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


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

当然可以,只要该值超出float.

于 2016-11-25T13:16:04.340 回答
10

由于源是常量表达式,这些情况不会发生溢出,因此不会触发缩小转换错误。

(强调我的)

从 long double 到 double 或到 float 的转换以及从 double 到 float的转换,除非源是常量表达式并且不会发生溢出

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

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 列表初始化 (强调我的)

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

于 2016-11-25T13:15:23.153 回答