Should this perhaps be considered a bug? Below is a minimal test
case for a type of calculation that occurs in my real code. It works
as expected when compiled without optimization, but produces what
seems like a wrong result when compiled with -O2, using both gcc
10.3.1 20210422 on Fedora and gcc 11.1.0-1 on Arch Linux. I realize
there's a newer gcc release but it's not yet available for Arch, and
looking at https://gcc.gnu.org/gcc-11/changes.html I didn't see
anything to suggest that something relevant has changed.
<test-case>
#include <stdio.h>
#include <limits.h>
int test (int *pk, int n)
{
int err = 0;
if (*pk > n) {
err = 1;
if (*pk > 2e9) {
int k = *pk + n - INT_MAX;
*pk = k;
if (k > 0) {
printf("Got positive revised k = %d\n", k);
err = 0;
} else {
printf("k = %d tests as non-positive?!\n", k);
}
}
}
return err;
}
int main (void)
{
int k = INT_MAX - 10;
int err;
err = test(&k, 20);
printf("main: err = %d\n", err);
return 0;
}
</test-case>
What strikes me as "seems wrong" is that the "(k > 0)" branch in
test() is not taken, although in the alternative branch it turns out
that k = 10. This can be fixed by using the "volatile" keyword in
front of the statement "int k = *pk + n - INT_MAX;" or by
parenthesizing (n - INT_MAX) in that statement.
I can see the case for assuming that k can't be positive if one
thinks of the expression as (*pk + n) - INT_MAX, since (*pk + n)
can't be greater than INT_MAX in context, being the sum of two ints.
All the same, since gcc does in fact end up assigning the value 10
to k the optimization seems a risky one.
--
Allin Cottrell
Department of Economics
Wake Forest University