奇妙なクラッシュが発生しています。そして、それは私のコードのバグなのか、それともコンパイラーのバグなのか疑問に思います。次の C++ コードを Microsoft Visual Studio 2010 で最適化されたリリース ビルドとしてコンパイルすると、マークされた行でクラッシュします。
struct tup { int x; int y; };
class C
{
public:
struct tup* p;
struct tup* operator--() { return --p; }
struct tup* operator++(int) { return p++; }
virtual void Reset() { p = 0;}
};
int main ()
{
C c;
volatile int x = 0;
struct tup v1;
struct tup v2 = {0, x};
c.p = &v1;
(*(c++)) = v2;
struct tup i = (*(--c)); // crash! (dereferencing a NULL-pointer)
return i.x;
}
逆アセンブルを見ると、クラッシュする必要があることは明らかです。
int _tmain(int argc, _TCHAR* argv[])
{
00CE1000 push ebp
00CE1001 mov ebp,esp
00CE1003 sub esp,0Ch
C c;
volatile int x = 0;
00CE1006 xor eax,eax
00CE1008 mov dword ptr [x],eax
struct tup v1;
struct tup v2 = {0, x};
00CE100B mov ecx,dword ptr [x]
c.p = &v1;
(*(c++)) = v2;
00CE100E mov dword ptr [ebp-8],ecx
struct tup i = (*(--c));
00CE1011 mov ecx,dword ptr [x]
00CE1014 mov dword ptr [v1],eax
00CE1017 mov eax,dword ptr [ecx]
00CE1019 mov ecx,dword ptr [ecx+4]
00CE101C mov dword ptr [ebp-8],ecx
return i.x;
}
00CE101F mov esp,ebp
00CE1021 pop ebp
00CE1022 ret
オフセット 00CE1008 で、x に 0 を書き込みます。
オフセット 00CE100B で x (0) を ecx に読み込みます
オフセット 00CE1017 で、その 0 ポインターを逆参照します。
考えられる理由は 2 つあります。
私のコードに未定義の動作の微妙な (またはそれほど微妙ではない?) ケースがあり、コンパイラがこの未定義の動作をクラッシュに「最適化」します。
またはコンパイラのバグがあります
問題の原因が何かわかりますか?
ありがとうございました、
ジョナス
編集:「無効な場所へのポインター」に関するコメントに対処するには
v1
bestruct tup v1[10];
と setに変更するとc.p = &v1[0];
、無効な場所へのポインターはなくなります。しかし、私はまだ同じ行動を観察できます。逆アセンブルはわずかに異なっているように見えますが、それでもクラッシュがあり、これは 0 を ecx にロードして逆参照することによって引き起こされます。
編集:結論
したがって、おそらくバグです。変更するとクラッシュが消えることがわかりました
struct tup* operator--() { return --p; }
に
struct tup* operator--() { --p; return p; }
bames53 が教えてくれるように、クラッシュは VS2011 では発生せず、修正されたに違いないと結論付けています。
それにもかかわらず、私は次の 2 つの理由から、そのバグを報告することにしました。
バグは VS2011 にまだ存在する可能性があります。私のコードがバグを引き起こさないようにオプティマイザーが変更されたのかもしれません。
volative
(バグは非常に微妙なようです。またはを削除すると発生しませんvirtual void Reset()
)私の回避策がクラッシュを除外するための信頼できる方法であるかどうか、または他の場所でコードを変更するとバグが再発する可能性があるかどうかを知りたいです。
リンクは次のとおりです。
https://connect.microsoft.com/VisualStudio/feedback/details/741628/error-in-code-generation-for-x86