为什么编译器(clang,gcc)在执行此操作时不警告缩小转换
float a{3.1231231241234123512354123512341235123541235};
float a = {double(3.1231231241234123512354123512341235123541235)}
我期待一个警告,因为我使用大括号进行显式值初始化。按照这个答案链接它应该吐出一个错误。
为什么编译器(clang,gcc)在执行此操作时不警告缩小转换
float a{3.1231231241234123512354123512341235123541235};
float a = {double(3.1231231241234123512354123512341235123541235)}
我期待一个警告,因为我使用大括号进行显式值初始化。按照这个答案链接它应该吐出一个错误。
[dcl.init.list]/§7(标准草案)
缩小转换是隐式转换
...
- 从 long double 到 double 或 float,或从 double 到 float,除非源是常量表达式并且转换后的实际值在可以表示的值范围内(即使不能精确表示),或
...
表达式3.14159
和double(3.141)
都是常量表达式,其值在 可表示的值范围内float
。因此,转换并没有按照标准的定义缩小,也不需要就转换发出警告。
但对于较长的输入,它也不会发出警告
当然可以,只要该值超出float
.
由于源是常量表达式,这些情况不会发生溢出,因此不会触发缩小转换错误。
(强调我的)
从 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,除非源是常量表达式并且转换后的实际值在可以表示的值范围内(即使不能精确表示),或