c++ - C++ 编译器如何设法发出完全没有意义的代码?

标签 c++ visual-c++ compiler-construction undefined-behavior

<分区>

这里是代码 from this question 的略微修改版本:

#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

是的,我知道在未定义行为的情况下,任何事情都是允许的。但是这段代码完全没有意义,编译器就是一个程序,所以我不希望从中得到毫无意义的东西。

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

最佳答案

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

关于c++ - C++ 编译器如何设法发出完全没有意义的代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14453371/

相关文章:

c++ - 将 int 矩阵数组放入 C++ 对象时出现问题

c++ - 为什么我不能在我的程序中声明一个字符串 : "string is undeclared identifier"

java - 使用 JFlex/CUP 构建编译器并解决一些问题

compiler-construction - 给定一个指令地址,能否确定包含它的函数的起始地址?

c++ - 假设安装了 GCC 和 G++ 如何编译使用 boost 库的文件? (线程)

c++ - 修改基类,使更改反射(reflect)在派生类中

c++ - 在 SELECT 中拆分一个 varbinary

c++ - 哪个版本的 GCC 引入了对原子内置函数的支持?

c++ - 如何从 C++ 程序运行 regasm.exe?

c++ - vector <complex> 的 Boost.Serialize 错误