コンパイラをgcc4.6にアップグレードしたところ、これらの警告がいくつか表示されます。現時点では、コードベースはc ++ 0xでコンパイルできる状態ではなく、とにかく、これをprodで実行したくないので(少なくともまだ)、この警告を削除するための修正が必要でした。
警告は通常、次のような理由で発生します。
struct SomeDataPage
{
// members
char vData[SOME_SIZE];
};
後で、これは次のように使用されます
SomeDataPage page;
new(page.vData) SomeType(); // non-trivial constructor
たとえば、読んだり、更新したり、戻ったりするには、次のキャストが発生していました
reinterpret_cast<SomeType*>(page.vData)->some_member();
これは4.4で問題ありませんでした。4.6では、上記は以下を生成します。
警告:型のパンニングされたポインタは厳密なエイリアスルールに違反します
このエラーを取り除くためのクリーンな方法は、を使用することですがunion
、前述のように、c ++ 0x(したがって無制限のユニオン)を使用できないため、以下の恐ろしいハックを採用しました-警告はなくなりました、しかし私は鼻のデーモンを呼び出す可能性がありますか?
static_cast<SomeType*>(reinterpret_cast<void*>(page.vData))->some_member();
これは問題なく機能しているように見え(ここの簡単な例を参照:http ://www.ideone.com/9p3MS )、警告は生成されません。これはc ++ 0xまで使用しても問題ありませんか(様式的な意味ではありません)。
注:私は一般的に使用したくない-fno-strict-aliasing
...
編集:私は間違っていたようです、同じ警告が4.4にあります、私たちは最近これを変更しただけだと思います(コンパイラの問題である可能性は常に低いです)、しかし問題はまだ残っています。
編集:さらなる調査により、いくつかの興味深い情報が得られました。コードが次のように2行に分割されている場合、キャストを実行してメンバー関数を1行で呼び出すことが、警告の原因であるようです。
SomeType* ptr = reinterpret_cast<SomeType*>(page.vData);
ptr->some_method();
これは実際には警告を生成しません。その結果、ideoneの簡単な例に欠陥があり、さらに重要なことに、上記のハックでは警告が修正されません。修正する唯一の方法は、キャストから関数呼び出しを分割することです。キャストはとして残すことができますreinterpret_cast
。