15

を使用して非常に奇妙な問題が発生してい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;
}

私はいくぶん立ち往生しており、これはコンパイラのバグだと考えています。何かご意見は?

4

2 に答える 2

18

実際、これは gcc の既知の問題です。gcc は、不正確な初期化されていない変数
を報告することで有名です。 欠点は正式に指摘されており、欠点を克服するためのイニシアチブがあります:初期化されていない警告の改善:

GNU Compiler Collection は、オプションで初期化されていない変数を使用することについて警告します-Wuninitialized。ただし、現在の実装にはいくつかの欠点があると認識されています。一方では、一部のユーザーは、より詳細で一貫した警告を求めています。一方、一部のユーザーは、警告をできるだけ少なくしたいと考えています。このプロジェクトの目標は、両方の可能性を実装すると同時に、現在の機能を改善することです。

このイニシアチブは、より良い警告を提供することを目的としており、あなたのケースと同様のケースを引用しています。関連する部分は次のとおりです。

ユーザーが誤検知として理解するものは、特定のユーザーによって異なる場合があります。一部のユーザーは、現在の環境と組み合わせたオプティマイザーのアクションのために非表示になっているケースに関心があります。ただし、コンパイルされたコードでは発生しないため、そのケースは隠されているため、多くのユーザーはそうではありません。標準的な例は

int x;
if (f ())
     x = 3;
return x;

ここで、'f' は現在の環境に対して常にゼロ以外を返すため、最適化によって除外される可能性があります。ここでは、'f' が他の場所でコンパイルされたときに 0 を返す可能性があるため、ユーザーのグループが初期化されていない警告を取得したいと考えています。しかし、他のグループのユーザーは、コンパイル中の実行可能ファイルでは発生しない状況についての誤った警告と考えるでしょう。

于 2013-01-03T04:06:31.963 に答える