'Why does my for loop not stop when I use an int32_t loop variable? [duplicate]

In my program, I found the loop unable to exit correctly when i is int32_t. It seems like integer overflow, and is much larger than 10, and the loop does not stop. Please tell me what happened and how I can avoid this error in a large project.

#include <iostream>
#include <stdint.h>
int f(int n){

    for (int32_t i = 0; i < 10; ++i)
    {
        int64_t time = 4500000000 +  (i) * 500000000;
        std::cout << time<< " i: " << i << std::endl;

    }
    return 0;
}

int main ()
{
    return f(10);
}

code link

c++


Solution 1:[1]

If you use GCC 11.2.0 and the -Wall -O2 options, you will see a warning about undefined behavior:

test.cpp: In function 'int f(int)':
test.cpp:7:42: warning: iteration 5 invokes undefined behavior [-Waggressive-loop-optimizations]
    7 |         int64_t time = 4500000000 +  (i) * 500000000;
      |                                      ~~~~^~~~~~~~~~~
test.cpp:5:27: note: within this loop
    5 |     for (int32_t i = 0; i < 10; ++i)
      |                         ~~^~~~

The compiler knows that 5 * 500000000 is too large to fit in an int (which is typically 32-bit). Signed integer overflow is undefined behavior in C++. Therefore, the compiler is free to assume that this overflow never happens, so it will assume that i can never reach 10, so it can get rid of the part of your for loop that checks i < 10. I know that sounds crazy, but if your program does undefined behavior, the compiler is free to do whatever it wants.

Just add some casts to specify that you want to do 64-bit arithmetic. This eliminates the warnings, the overflows, and the undefined behavior:

int64_t time = (int64_t)4500000000 + i * (int64_t)500000000;

Update: For a larger project that could have more bugs, you might consider using GCC's -fwrapv option, which makes the behavior of signed integer overflow be defined. You could also use -fsanitize=signed-integer-overflow or -fsanitize=undefined to detect these issues at run time, if your toolchain supports those options.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1