2016-05-12 6 views
7

私は最近、CおよびC++言語標準が「厳密なエイリアシング」ルールを持っていることに驚きました。本質的に、このルールは、異なるタイプの変数が同じメモリ位置を参照することを禁じている。一例として、Visual C++は "厳密なエイリアシング"をサポートしていますか?

char buffer[4] = { 0x55, 0x66, 0x77, 0x88 }; 
int32 *p = (int32*)&buffer[0]; // illegal because buffer[0] and *p are different types 

は、私はと対話プロC++開発者のほとんどは、このルールに精通していません。私の研究に基づいて、それは主にGCC/G ++/CLANGユーザーに影響を与えるようです。 Visual C++ではこのルールの有効化/無効化がサポートされていますか?もしそうなら、どうやってそうするのですか?

ありがとう

+0

AFAIK MSVCは常にノーマルエイリアスを設定しているかのように動作します –

+3

1-800サポート電話機数。そうではありません。 –

+1

lol @ 1-800サポート番号: – digitale

答えて

6

"厳格なエイリアシングは、" プログラムではなく、コンパイラを制限するC++の規則です。ルール違反は未定義の動作なので、診断不要コンパイラはこれをサポートする必要はありません。

つまり、マイクロソフトでは、最適化の適用がやや攻撃的です。先週、GCCがすでに数年間想定してきた新しいオプティマイザassumes no signed overflowを発表しました。厳密なエイリアシングはいくつかのWindowsヘッダーを破るので、最初に修正する必要があります。 (一部のタイプはunionが含まれているかのように動作しますが、形式的にはそのように定義されていません)

+1

コンパイラがnビット整数の加算、減算、または乗算の結果が整数セマンティクスを使用すると約束できる手段があれば、IMHOに役立つでしょうオーバーフローの場合には、* which *整数の選択は非決定論的である可能性があります。そのような動作上の制約に依存する可能性のあるコードは、多くの場合、すべてのコストでオーバーフローを防止しなければならないコードより効率的である可能性があります。 – supercat

+0

@supercat:コンパイラのヘルプが本当に必要かどうかは分かりません。あなたはそれをライブラリに実装できるように思えます。 'unsigned'を内部的に使用します。その演算は、2の補数符号付き算術とほぼ1:1に対応します。 – MSalters

+1

'int 'の範囲内で常に結果を返すような方法でこのような数式を実行するライブラリを書くことはできますが、コードやコンパイラオプションを問わずラッピングの動作は効率の大きな障害になる可能性があります。プログラマがコンパイラがレールを飛ばすことを避けることができるようにラッピング動作を強制しなければならない場合、コンパイラはラッピングを無視する自由を持っていれば生成できるものほど効率的なコードを生成できません(例えば、もしxxとyがループ不変であれば、コンパイラは 'yx'がオーバーフローしない場合に1つのループを使うことができます... – supercat

関連する問題