C++ 编译器如何设法发出完全无意义的代码? [已关闭]

问题描述 投票:0回答:2

这是代码的稍微修改版本来自这个问题

#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

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

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

c++ visual-c++ undefined-behavior
2个回答
1
投票

从编译器的角度来看,

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


1
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.