为何下述C++代码用G++ 8.2.0加-O2参数编译后运行无输出?
代码开O2优化无输出问题分析
复现说明
将以下代码保存为test.cpp:
#include <iostream> int foo(int x, int y) { } int main() { int x = 1; int y = 2; int ret = foo(x, y); std::cout << y << std::endl; return 0; }
编译命令:
$ g++ -O2 -o test test.cpp
运行命令:
$ ./test
测试现象:G++ 8.2.0版本下,开启-O2优化时运行无任何输出,移除-O2参数编译后运行可正常打印2。
核心原因分析
1. 代码本身存在未定义行为
返回值类型为int的foo函数没有编写任何return语句,且调用foo时将其返回值赋值给了变量ret,这属于C标准明确规定的未定义行为(Undefined Behavior, UB)。C标准对未定义行为的执行结果没有任何约束,编译器有权基于「代码不存在未定义行为」的假设做任意优化处理。
2. O2优化下的死代码裁剪逻辑
GCC 8.2.0开启-O2优化时会执行激进的路径裁剪优化:
- 编译器检测到
foo函数存在无返回值的未定义行为,判定调用foo之后的所有代码路径都是非法不可达的 - 因此直接将
foo调用后的std::cout输出逻辑完全优化删除,程序执行完foo调用后就直接结束,自然不会产生任何输出
3. 无优化时正常输出的原因
关闭-O2优化时,编译器不会执行上述激进的未定义行为相关优化,代码会按照编写的原始逻辑顺序执行:
- 即使
foo没有返回值,栈上的y变量的值仍然保留初始化的2 - 后续的
std::cout逻辑可以正常执行,因此会正确输出2
内容的提问来源于stack exchange,提问作者Guibao Wang
相关产品推荐
相关产品推荐

