ここからコードスニペットがあります:
volatile int volatileInt;
int usualInt;
void function (unsigned x, unsigned y, unsigned z)
{
volatileInt = 0;
usualInt = (x % y) / z;
}
int main()
{
function(rand(), rand(), rand());
}
これをVisualC++ 10でコンパイルして/O2
、この逆アセンブリを取得します。
00403940 push ebx
00403941 push esi
276: function(rand(), rand(), rand());
00403942 mov esi,dword ptr [__imp__rand (4050C0h)]
00403948 push edi
00403949 call esi
0040394B mov edi,eax
0040394D call esi
0040394F mov ebx,eax
00403951 call esi
00403953 xor edx,edx
00403955 div eax,ebx <<<< possible UB
00403957 mov dword ptr [volatileInt (4074D0h)],0
00403961 mov eax,edx
00403963 xor edx,edx
00403965 div eax,edi <<<< possible UB
00403967 pop edi
00403968 pop esi
00403969 pop ebx
0040396A mov dword ptr [usualInt (4074CCh)],eax
277: return 0;
0040396F xor eax,eax
00403971 ret
「mod」と「div」の2つの演算があり、実行時に2番目のオペランドがゼロの場合にUBを生成する可能性があることに注意してください。放出されたコードでは、両方ともdiv
構造化例外をトリガーしてプログラムをクラッシュさせるオペコードで実装されています。第2オペランドはゼロです。
1つ目は変数が変更さdiv
れる前ですが、2つ目は変更後です。volatile int
volatile int
したがって、x
がゼロの場合、プログラムは変更せずにクラッシュしますvolatile int
が、x
がゼロ以外でy
ゼロの場合、プログラムは変更volatile int
されてからクラッシュします。
したがって、ゼロであるかゼロであるかに応じてx
、y
プログラムは異なる観察可能な動作を示します。
観察可能な動作に影響を与えるコードを含む可能性のあるUBとのコードのそのようなインターリーブは許可されていますか?