Can anybody explain the following behavior of the GCC-7 compiler?
// main.cpp
#include <iostream>
using namespace std;
int main()
{
    int a = -2147483648;
    int b = -a;
    cout << "a == " << dec << a << " == 0x" << hex << a << "\n";
    cout << "b == " << dec << b << " == 0x" << hex << b << "\n";
    if (a > 0)
        cout << "a > 0      // ERROR\n";
    else
        cout << "a <= 0     // OK\n";
    if (b > 0)
        cout << "b > 0      // ERROR\n\n";
    else
        cout << "b <= 0     // OK\n\n";
    int aa[] = { -2147483648, 0 };
    int bb = -aa[0];
    cout << "aa[0] == " << dec << aa[0] << " == 0x" << hex << aa[0] << "\n";
    cout << "bb    == " << dec << bb << " == 0x" << hex << bb << "\n";
    if (aa[0] > 0)
        cout << "aa[0] > 0  // ERROR\n";
    else
        cout << "aa[0] <= 0 // OK\n";
    if (bb > 0)
        cout << "bb > 0     // ERROR\n\n";
    else
        cout << "bb <= 0    // OK\n\n";
    cin.get();
    return 0;
}
Compilation without optimization: g++ main.cpp
Output:
a == -2147483648 == 0x80000000
b == -2147483648 == 0x80000000
a <= 0     // OK
b <= 0     // OK
aa[0] == -2147483648 == 0x80000000
bb    == -2147483648 == 0x80000000
aa[0] <= 0 // OK
bb <= 0    // OK
Compilation with optimization: g++ -O2 main.cpp
Output:
a == -2147483648 == 0x80000000
b == -2147483648 == 0x80000000
a <= 0     // OK
b <= 0     // OK
aa[0] == -2147483648 == 0x80000000
bb    == -2147483648 == 0x80000000
aa[0] <= 0 // OK
bb > 0     // ERROR
Is this undefined behavior or a compiler bug?
GCC version: gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
This is undefined behavior. Presumably on your machine int is 32-bit, whose range is -2147483648 to 2147483647. Trying to negate -2147483648 results in overflow (not Stack Overflow :P) which is undefined behavior (unsigned overflow is defined, but not for signed.) Therefore the compiler can do anything it likes.
User contributions licensed under CC BY-SA 3.0