简体   繁体   中英

Why is my compiler "optimizing" this for loop into an infinite loop when compiled with -O3 in C++

I am trying to understand what optimization process causes the following code to produce an infinite loop when compiled with the -O3 optimization flag. To get it out of the way, I understand that the real root cause of the issue is the lack of a return in this non void function , I happened on this interesting behavior while part way through implementing this code on an embedded system and had not yet added the return as I was not using the return value at that point.

My question is more about the optimization process and how whatever it's doing could help in other cases/what the 'optimized' logic looks like.

For a little more context, I see this behavior when using both the c++ compiler in ubuntu (c++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0) as well as the aarch64-linux-gnu-g++ compiler shipped with Xilinx Vitis 2020.2 (and running on their respective platforms of course).

Minimum reproducible example (that I have so far created):

#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();
}

When compiling with c++./broken_loop_test.cpp -o test_local -O3 or the ARM equiv. the output of the loop is infinite and I have run it until the 32b int wraps around. Without optimization, it works as I would expect. If I simply return 0 after the for loop, it also works with optimization.

My naive suspicion is that because there is no return outside the loop, the compiler expects that I will return from or break out from inside the loop, and therefor removes the check/branch that would test the loop condition, but I was wondering what I could look into to get more information on this specific topic (and optimization in general, it's been a while since my last course in compiler design) and I am not comfortable enough with ASM to confidently identify the issue there.

Any help would be appreciated, thank you!

Because this section is required, I will note that I have tried declaring volatile i as well as using different types of integer as well as casting the constant value and doing more/less in the loop. All lead to the same behavior without a return statement.

Undefined behaviour results in time travel .

Your code is a good example of it.

You have undefined behaviour after the loop (a function that must return a value doesn't). Since the compiler is allowed to assume that UB never happens, it assumes that the loop never terminates, and compiles it accordingy.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM