Home > Net >  Why is my compiler "optimizing" this for loop into an infinite loop when compiled with -O3
Why is my compiler "optimizing" this for loop into an infinite loop when compiled with -O3

Time:11-30

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.

CodePudding user response:

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.

  • Related