C++ Signed/Unsigned Integer Overflow – Explanation

c++integer-overflow

I'm just starting to teach myself C++, and have begun learning about integer overflow. Out of curiosity I wrote some tests just to see what occurs with certain integer values.

Here's my program:

#include <iostream>

int main()
{
    int x(0);
    std::cout << x << std::endl;

    x = x + 2147483647;
    std::cout << x << std::endl;

    x = x + 1;
    std::cout << x << std::endl;
    std::cout << std::endl;

    unsigned int y(0);
    std::cout << y << std::endl;

    y = y + 4294967295;
    std::cout << y << std::endl;

    y = y + 1;
    std::cout << y << std::endl;
}

And here's the output:

0
2147483647
-2147483648

0
4294967295
0

The output surprised me a bit, and I'm wondering if someone could explain why this happened, OR if the unexpected-ness of these results is expected; so this may just be the result of my specific machine.

Best Answer

Signed integer overflow is undefined behaviour, while unsigned integer overflow is well-defined; the value wraps around. In other words, the value is modulo divided by 2bits, where bits is the number of bits in the data type. Since you've a 32-bit int

4294967295 + 1 = 4294967296 % 232 = 0

it results in 0 in the second case. The first case, from the language standpoint, is undefined.

However, most implementations employ 2's complement to implement signed integer types. A toy, signed 4-bit data type, implemented using 2's complement may be used to explain what happend in the first case. In this type

POS_MAX = 7 = 0111)2

NEG_MAX = -8 = 1000)2

The type can hold 24 = 16 states, 8 positive (0 to 7) and 8 negative (-1 to -8).

POS_MAX + 1 = 0111)2 + 1)2 = 1000)2

Since the first bit is set, it's a negative number, to find the actual value, do the inverse the two's complement (subtract 1 and flip bits)

1000)2 - 1)2 = 0111)2

~0111)2 = 1000)2 = 8

Thus the final value is -8. All this is not defined by the language but this is what happened in your case, specifically.

Related Question