gcc-4.7 (Ubuntu/Linaro 4.7.2-11precise2) 4.7.2
を使用すると非常に奇妙な問題が発生します。警告なしに次の有効なコードをコンパイルできません。
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1) ret = arg2 ? 1 : 2;
dostuff();
if (arg1) return ret;
return 0;
}
コンパイルオプションと出力:
$ gcc-4.7 -o test.o -c -Os test.c -Wall
test.c: In function ‘test’:
test.c:5:6: warning: ‘ret’ may be used uninitialized in this function [-Wmaybe-uninitialized]
ただし、次のコードは警告なしでコンパイルされます(アセンブリの効率は少し低下しますが)。
extern void dostuff(void);
int test(int arg1, int arg2)
{
int ret;
if (arg1 && arg2) ret = 1;
if (arg1 && !arg2) ret = 2;
dostuff();
if (arg1) return ret;
return 0;
}
私はやや立ち往生しており、これをコンパイラのバグと考えています。何かご意見は?
実際、これはgccの既知の問題です。
gccはレポートで有名です初期化されていない変数が正しくありません。
欠点は適切に指摘されており、欠点を克服するためのイニシアチブがあります。
初期化されていない警告の改善 :
GNUコンパイラコレクションは、オプション
-Wuninitialized
での初期化されていない変数の使用について警告します。ただし、現在の実装にはいくつかの認識された欠点があります。一方で、一部のユーザーはより詳細で一貫した警告一方、一部のユーザーは警告をできるだけ少なくしたいと考えています。このプロジェクトの目標は、両方の可能性を実装すると同時に、現在の機能を改善することです。
このイニシアチブは、より良い警告を提供することを目的としており、あなたのケースと同様のケースの例を引用しています。関連する部分は次のとおりです。
ユーザーが誤検知として理解する内容は、特定のユーザーによって異なる場合があります。一部のユーザーは、現在の環境と組み合わされたオプティマイザーのアクションのために隠されているケースに興味を持っています。ただし、コンパイルされたコードでは発生しないため、そのケースは非表示になっているため、多くのユーザーはそうではありません。正規の例は
int x;
if (f ())
x = 3;
return x;
ここで、「f」は現在の環境に対して常にゼロ以外を返すため、最適化することができます。ここで、ユーザーのグループは、他の場所でコンパイルすると「f」がゼロを返す可能性があるため、初期化されていない警告を受け取りたいと考えています。それでも、他のユーザーグループは、コンパイル中の実行可能ファイルでは発生しない状況についての誤った警告を検討します。