2009-04-16 11 views

答えて

17

エイリアシングを非常に詳しく説明しているページがあります。here

また、いくつかのトピックがありますherehere。要約すると、コンパイラは、異なるタイプの2つのポインタが同じ場所にアクセスしている(つまり、毎回値を読み込んで最適化できない)場合、データの値を仮定することはできません。

これは、厳密なエイリアシングが強制されていない場合にのみ発生します。厳密なエイリアシングオプション:

  • GCC:-fstrictエイリアシング[デフォルト]-fno-厳密エイリアシング
  • MSVC: 厳密なエイリアシングがデフォルトでオフになっています。 (誰かがそれをオンにする方法を知っている場合は、 そう言ってください。)

のmain.cにこのコードをコピー&ペースト:

void f(unsigned u) 
{ 
    unsigned short* const bad = (unsigned short*)&u; 
} 

int main(void) 
{ 
    f(5); 

    return 0; 
} 

その後これらのオプションを使用してコードをコンパイルします。

gccのmain.cの-Wall -O2

そして、あなたが取得します:

のmain.c:3: を警告:逆参照型punned ポインタが厳しいエイリアシング ルール

を中断します

GCC main.cの-fno-厳密-別名:と

無効エイリアシング -Wall -O2

警告が消えます。 (または、壁を取り出すだけですが、コンパイルしないでコンパイルしないでください)

私はMSVCで警告を受けることができないかもしれません。

+0

+1ですが、厳密なエイリアシングが観察されない場合は、コンパイラがその仮定を立てられないことを明確にしてください。 –

+1

パーフェクト! :) MSVC++では厳密なエイリアシングのオプションがないように思います。それには__restrictと__declspec(制限)がありますが、これは個々のケースで使用できます。 –

+0

"-fno-strict-aliasing [デフォルト]と-fno-strict-aliasing"のように見えます。デフォルトでは-fno-strict-aliasingではなく-fstrict-aliasingの (少なくとも最新のGCCでは)どのような場合でも、リストされている2つのGCCオプションのうちの1つは-fstrict-aliasingでなければなりません。そして今は両方とも-fno-strict-aliasingと言います。 – tialaramex

関連する問題