次のプログラムでは、5行目は予想どおりoverflow warningを示していますが、驚くべきことに、4行目はGCCで警告を出していません: http://www.ideone.com/U0BXn
int main()
{
int i = 256;
char c1 = i; //line 4
char c2 = 256; //line 5
return 0;
}
両方の行でoverflow警告を表示する必要があると考えていました。それとも私が見逃しているものはありますか?
私がこの実験をするようになったトピックはこれです: typedef型チェック?
そこで私は次のように述べました(実行すると、期待したとおりに表示されなかったため、回答から削除しました)。
//However, you'll get warning for this case:
typedef int T1;
typedef char T2;
T1 x = 256;
T2 y = x; //possible overflow warning! (but it doesn't give warning :()
-Wall
には多くのオプションが含まれていません。 -Wconversion
はその1つであり、興味のある動作について警告します。
int
値をchar
オブジェクトに割り当てる一般的な場合、コンパイラーはint
がchar
の範囲外であるかどうかを認識しません。
実際の警告をさらに詳しく見てみましょう。
warning: overflow in implicit constant conversion
コンパイラが警告することができるのは、定数がchar
に変換されているこの特定の場合です。同様に、i
の宣言をconst
に変更した場合:
const int i = 256;
c2
に割り当てられている値は定数式であるため、警告も表示されます。
また、変換は技術的に「オーバーフロー」しないため、警告は誤解を招く可能性があることにも注意してください。算術オーバーフローにより、C++で未定義の動作が発生します。ナローイング変換(int
がchar
より大きい場合、int
からchar
への変換)は、実装によって定義された変換をもたらします。
さて、5行目は、どのコンパイラーも直接見ることができる明らかなエラーであり、alwaysエラーです。行4では、エラーを検出するために少なくともsomeデータフロー分析が必要です。おそらく、これはサイトで使用されている設定では行われていないか、コンパイラの作成者がこれを理解するのに十分重要であるとは考えていませんでした。
GCC 4.3以降、-Wconversion
のセマンティクスは値を変更する可能性のある暗黙の変換を検出するように更新されましたが、それ以外の場合は-Wsign-conversion
も有効にする必要があります。符号付き型と符号なし型の間の強制型変換により、数値の符号が変わる可能性があります。
CCC 4.3(以前はまだリリースされていなかった)より前のCrazy Eddieの発言に反して、-Wconversion
は暗黙的な型変換などによって引き起こされる問題を総称的にチェックしませんでした。むしろ、プログラムが古いスタイルのK&R関数プロトタイプを使用した場合とは異なる動作をするかどうかを確認しました。
これは、すべての暗黙的な型変換/強制の問題について警告を発しただけでなく、いくつかの優れたコードが不必要な警告を発したことも意味しました。そしてもちろん、そのようなプロトタイプは有効なC++ではないため、g++
でエラーが発生することはありません。