是否可以获得UB代码是否可以保证?

sha*_*oth 6 c++ compiler-optimization undefined-behavior visual-c++

我有一个代码片段从这里:

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());
}
Run Code Online (Sandbox Code Playgroud)

我使用Visual C++ 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  
Run Code Online (Sandbox Code Playgroud)

请注意,有两个操作 - "mod"和"div",如果第二个操作数在运行时为零,则可能产生UB.在发出的代码中,两个都是用div操作码实现的,这些操作码将触发结构化异常并且程序崩溃是第二个操作数为零.

第一个div是在volatile int变量修改之前,但第二个是在volatile int修改之后.

因此,如果x为零则程序崩溃而不修改volatile int但是如果x非零并且y为零,则程序修改volatile int然后崩溃.

所以,这取决于是否xy程序为零将表现出不同的观察到的行为.

是否允许使用可能影响可观察行为的代码的代码与可能的UB进行交错?

ham*_*ene 7

是的,允许这种实现.见1.9/5:

执行格式良好的程序的一致实现应该产生与具有相同程序和相同输入的抽象机的相应实例的可能执行之一相同的可观察行为.但是,如果任何此类执行包含未定义的操作,则此国际标准不要求使用该输入执行该程序的实现(甚至不考虑第一个未定义操作之前的操作).


eca*_*mur 5

我认为第1.9:4条与此有关:

本国际标准中描述的某些其他操作未定义(例如,尝试修改const对象的效果).[注意:本国际标准对包含未定义行为的程序的行为没有要求. - 尾注]

据我了解,这意味着如果程序执行最终导致未定义的行为,则程序的整个可观察行为是未定义的.