これを行うときに、コンパイラ (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
EDIT (より長い入力用)
値が で正確に表現できなくてもfloat
、オーバーフローは発生しないため、許容されます。
$8.6.4/7.2 リストの初期化 (強調鉱山)
long double から double または float へ、または double から float へ。ただし、ソースが定数式であり、変換後の実際の値が (正確に表現できない場合でも)表現できる値の範囲内にある場合を除きます。