1

这是此问题的代码的略微修改版本:

#pragma warning(default:4716)
int recur(int i) 
{ 
   int result;
   result = (i>1 ? i - recur(i/2) : 3);
   // return intentionally omitted
}

int main()
{
    return recur(0);
}

请注意,recur()省略return,因此其行为未定义。下面是 Visual C++ 10 为此代码发出的内容:

 316: int main()
 317: {
00403940  push        ecx  
 318:   return recur(0);
00403941  mov         eax,dword ptr [esp]  
 319: }
00403944  pop         ecx  
00403945  ret

是的,我知道在未定义行为的情况下,任何事情都是允许的。但是这段代码完全没有意义,编译器就是一个程序,所以我不会指望它会做出毫无意义的事情。

编译器如何设法发出完全无意义的代码?

4

2 回答 2

1

由于代码具有未定义的行为,编译器实际上可以做任何事情,包括生成无意义的代码。

这里最有可能发生的是编译器忠实地编译了您的代码并将其传递给优化器,优化器进行了一些内联和常量表达式折叠。
在损坏的代码上使用该过程恰好会导致您看到的结果。

于 2013-01-22T08:47:20.327 回答
1

从编译器的角度来看,return smth;语句意味着简单的事情:生成一些代码以根据调用约定将结果返回给调用者(对于“C”、x86/amd64 和普通类型通常意味着将 smth 放入eax/rax寄存器)。如果你错过了return这只是意味着编译器你不会生成这样的代码(mov result, %eax)。通常它会导致警告(至少):在返回 non-void 的函数中没有 return 语句。但它可能很好,如果函数体有asm部分而不是编译器......在那种(罕见的)情况下,警告通常被 #pragma 或相应的命令行选项抑制。是的,一般来说错过返回会导致 UB ......

于 2013-01-22T07:41:53.837 回答