8

特定の問題、自己回答、およびそれに対するコメントに続いて、それが適切な解決策であるか、回避策/ハックであるか、または単に間違っているかを理解したいと思います。

具体的には、コードを書き直しました。

T x = ...;
if (*reinterpret_cast <int*> (&x) == 0)
  ...

として:

T x = ...;
if (*reinterpret_cast <volatile int*> (&x) == 0)
  ...

volatileポインタへの修飾子付き。

T私の状況のようintに扱うことが理にかなっていると仮定しましょう。参照を介したこのアクセスは、volatileポインターエイリアシングの問題を解決しますか?

参考までに、仕様から:

[注:オブジェクトの値は実装で検出できない手段によって変更される可能性があるため、volatileは、オブジェクトが関与する積極的な最適化を回避するための実装へのヒントです。詳細なセマンティクスについては、1.9を参照してください。一般に、volatileのセマンティクスは、C++でもCと同じであることが意図されています。— end note]

編集:

上記のコードは、少なくともGCC4.5で私の問題を解決しました。

4

2 に答える 2

17

揮発性は、ここで未定義の動作を回避するのに役立ちません。したがって、GCC で動作する場合は運がいいです。

T が POD であるとしましょう。次に、これを行う適切な方法は

T x = …;
int i;
memcpy(&i,&x,sizeof i);
if (i==0)
  …

そこには!厳密なエイリアシングの問題も、メモリ アラインメントの問題もありません。GCC は memcpy を組み込み関数として扱います (この場合、関数呼び出しは挿入されません)。

于 2010-06-05T19:59:32.493 に答える
-7

揮発性は、ここで未定義の動作を回避するのに役立ちません。

まあ、volatile標準では何かがやや不明確です。私はあなたの答えにほぼ同意しましたが、今は少し反対したいと思います。

意味を理解するためにvolatile、ほとんどの人、特に一部のコンパイラ作成者にとって、標準は明確ではありません。考えたほうがいいです: 使用する場合volatile(および使用する場合のみ)、C/C++ はかなり高レベルのアセンブリです。

左辺値に書き込む場合volatile、コンパイラは STORE を発行するか、1 つでは不十分な場合は複数の STORE を発行します (volatileアトミックを意味するものではありません)。

左辺値に書き込む場合volatile、コンパイラは LOAD を発行するか、1 つでは不十分な場合は複数の LOAD を発行します。

もちろん、明示的な LOAD または STORE がない場合、コンパイラは LOAD または STORE を意味する命令を発行するだけです。

Sellibitze は最良の解決策を提供しました。ビットの再解釈に使用します。memcpy

しかし、メモリ領域へのすべてのアクセスが左辺値で行われる場合volatile厳密なエイリアシング規則が適用されないことは完全に明らかです。これがあなたの質問に対する答えです。

于 2012-07-15T00:35:56.567 に答える