Can someone explain to me how this is undefined behavior?

Viewed 124

I have this simple program which I compile with -O2.

Compiler version : g++ (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

#include <cstdlib>

constexpr size_t NUM_ELEMENTS = 10000;

void init(float *a) {
    a[0] = 42;

    size_t i;
    for (i = 1; i < NUM_ELEMENTS - 2; i += 3) {
        a[i] = a[i+1] = a[i+2] = 42;
    }

    while (i < NUM_ELEMENTS) {
        a[i] = 42;
        i++;
    }
}

int main() {
    float a[NUM_ELEMENTS];
    init(a);
    return 0;
}

And g++ gives me this (inexplicable to me) warning

foo.cpp: In function ‘void init(float*)’:
foo.cpp:14:12: warning: iteration 4611686018427387903 invokes undefined behavior [-Waggressive-loop-optimizations]
   14 |         a[i] = 42;
      |            ^
foo.cpp:13:14: note: within this loop
   13 |     while (i < NUM_ELEMENTS) {
      |            ~~^~~~~~~~~~~~~~

If I change the while with the equivalent for (; i < NUM_ELEMENTS; i++) the warning goes away. If I change the array to global and I just access it in randomize WITHOUT passing it as a parameter, the warning goes away.

I've read similar SO questions which I understand, but this baffles me. If I had to guess, I'd say that g++ knows the while loop will never run (since i == 10000 at the end of the 1st loop) and it does some kind of aggressive transformation that leads to this warning? Help!

1 Answers

This appears to be a duplicate of a known bug in gcc that has to do with -Waggressive-loop-optimizations. But given that your example is much simpler than those I have seen in duplicates of that bug, I suggest you report the example to the confirmed bug report (see link).

Interestingly, this problem appears to exist only for -O2, not for -O1 and -O3 in the existing reports.

Related