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

时间:2012-07-18 09:20:26

标签: c++ visual-c++ compiler-optimization undefined-behavior

我有一个代码段from here

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());
}

我使用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  

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

第一个div位于修改volatile int变量之前,但第二个位于修改volatile int之后。

因此,如果x为零,程序会在不修改volatile int的情况下崩溃,但如果x非零并且y为零,则程序会修改volatile int和然后崩溃。

因此,根据xy是否为零,程序将表现出不同的可观察行为。

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

2 个答案:

答案 0 :(得分:7)

是的,允许此实现。见1.9 / 5:

  

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

答案 1 :(得分:5)

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

  

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

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

相关问题