GCC 4.5.2(Ubuntu 11.10 x64では32ビット用にコンパイルされますが、無効なアセンブリコードが生成されます)それ。最適化はすでに-O0であることに注意してください。あなたはそれが%のESIでm_p値を格納し、後でそれに返された値を追加します見ることができるようにGCCアセンブリコード生成のバグと回避策
9840 m_p += Get();
f689eff5: mov 0x8(%ebp),%eax
f689eff8: mov 0xd4(%eax),%eax
f689effe: mov %eax,%esi
f689f000: mov 0x8(%ebp),%eax
f689f003: mov %eax,(%esp)
f689f006: call 0xf66116a0
f689f00b: lea (%esi,%eax,1),%edx
f689f00e: mov 0x8(%ebp),%eax
f689f011: mov %edx,0xd4(%eax)
:
私は2つの機能があります。
inline long Class::Get()
{
long v = *(long*)(m_p);
m_p += 4;
return v;
}
inline void Class::Command()
{
m_p += Get();
}
GCC 4.5.2は、このアセンブリコードを生成し、 leaを使ってBUT :: Get()はm_pも変更します! GCCは認識していないようです。したがって、%esiの値は時代遅れであるため、バグm_pは正しくありません(4バイトは予想よりも少なくなります)。
私は
inline void Class::Command()
{
long v = Get();
m_p += v;
}
を使用してそれを修正することができます。しかし、私はバグが離れて行くにするために、コードを変更することなく、そのようないくつかのプラグマやなめらかに適用することができれば私は思ったんだけど。 gccのバージョンについては、私は指定されたものに固執しています。
'long v = *(long *)(m_p);'についての警告は表示されませんか?私はこれが型打ちで、技術的にUBだと信じていますか?このような危険なコードを書くつもりなら '-fno-strict-aliasing'を試してみてください。 –
いつでもキャストすることができます... –
いいえ、警告はオフです。しかし、私はそれがどのように関連しているか分かりません。そして、私はこのようなコードを書いていない、私はちょうどそれを使って作業しています。 – queen3