4

次のコードがあります。

struct A
{
    short b;
};

struct B
{
    double a;
};


void foo (struct B* src)
{
    struct B* b = src;
    struct A* a = (struct A*)src;

    b->a = sin(rand());

    if(a->b == rand())
    {
        printf("Where are you strict aliasing warnings?\n");
    }
}

次のコマンドラインでコードをコンパイルしています。

gcc -c -std=c99 -Wstrict-aliasing=2 -Wall -fstrict-aliasing -O3 foo.c

GCC 4.5.0 を使用しています。コンパイラが警告を出力することを期待していました:

 warning: dereferencing type-punned pointer will break strict-aliasing rules

しかし、そうではありません。他のケースでは警告を出力することができますが、この場合はなぜ出力されないのか疑問に思っています。これは厳密なエイリアシング規則を破る明らかな例ではありませんか?

4

1 に答える 1

1

言うためのGCCのドキュメント-Wstrict-aliasing=2(強調鉱山):

レベル 2: アグレッシブ、クイック、正確すぎない。まだ多くの偽陽性 (レベル 1 ほどではありませんが) があり、偽陰性はほとんどありません (ただし、レベル 1 を超える可能性があります)。レベル 1 とは異なり、アドレスが取得されたときにのみ警告します。不完全な型について警告します。フロントエンドでのみ実行されます。

あなたのコードはそれほどトリッキーではないように見えるので、なぜ偽陰性になるのかわかりませんが&、エイリアスを実行するために address-of 演算子を使用していないためかもしれません (それが意味することかもしれません) 「アドレスが取得されたときにのみ警告する」)


アップデート:

これは、address-of 演算子を使用していないためです。次のコードを foo.c ファイルに追加すると:

int usefoo(void)
{
    struct B myB = {0};

    foo( &myB);

    return 0;
}

警告が発行されます。

が別のコンパイル単位にある場合usefoo()、警告は発行されません。

于 2010-09-28T23:34:22.377 に答える