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.14159式とはどちらdouble(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

EDIT (より長い入力用)

値が で正確に表現できなくてもfloat、オーバーフローは発生しないため、許容されます。

$8.6.4/7.2 リストの初期化 (強調鉱山)

long double から double または float へ、または double から float へ。ただし、ソースが定数式であり、変換後の実際の値が (正確に表現できない場合でも)表現できる値の範囲内にある場合を除きます。

于 2016-11-25T13:15:23.153 に答える