我正在尝试理解优化过程是如何导致下列代码在使用 -O3 优化标志编译时产生无限循环的。顺带一提,我明白问题的真正原因在于该非 void 函数缺少返回,而我在嵌入式系统上实现这段代码的过程中遇到了这种有趣的行为,此时我还没有添加返回语句,因为那时我没有使用返回值。
我的问题更多地涉及优化过程,以及它是如何在其他情况下提高性能的/‘优化’逻辑的样子。额外提供信息,当我在 Ubuntu 使用 C++ 编译器(c++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0)和 Xilinx Vitis 2020.2 提供的 aarch64-linux-gnu-g++ 编译器时(分别在它们各自的平台上运行),都能看到这种行为。
最小可重现示例(目前我已创建):
我的问题更多地涉及优化过程,以及它是如何在其他情况下提高性能的/‘优化’逻辑的样子。额外提供信息,当我在 Ubuntu 使用 C++ 编译器(c++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0)和 Xilinx Vitis 2020.2 提供的 aarch64-linux-gnu-g++ 编译器时(分别在它们各自的平台上运行),都能看到这种行为。
最小可重现示例(目前我已创建):
#include <iostream>
int broken_for_loop(){
for (int i = 0; i < 10000; i+= 1000){
std::cout << i << std::endl;
}
}
int main(int argc, char const *argv[]){
broken_for_loop();
}
当使用c++ ./broken_loop_test.cpp -o test_local -O3
或ARM相应的编译命令进行编译时,循环的输出是无限的,并且我已经运行了直到32位整数溢出。没有优化时,它的工作方式符合我的期望。如果在for循环后简单地return 0
,则在进行优化时也可以正常工作。
我天真的怀疑是因为循环外没有返回,所以编译器希望我从循环内返回或中断,因此删除了测试循环条件的检查/分支,但我想知道可以查看什么内容以获取更多关于这个特定主题(以及优化的一般信息,自上次参加编译器设计课程以来,已经过了一段时间)的信息,而我对汇编语言不够自信,无法确定问题所在。
任何帮助都将不胜感激,谢谢!
由于需要此部分,我会注意到我尝试声明volatile i
,并使用不同类型的整数,以及将常量值转换和在循环中执行更多/更少的操作。所有情况都没有返回语句会导致相同的行为。
return
语句,代码就是不完整的,所以(大概)所有的赌注都是无效的。 - Adrian Molereturn
语句,g++和clang都会删除循环边界检查,并且根本不会从函数中返回。一个不无道理的推断可能是:“这个函数永远不会返回,所以循环永远不会终止,因此没有必要检查循环条件”。 - molbdnilo