Question

I have done some tests in VC++2010 mixing operands of different sizes that cause overflow in add operation:

int _tmain(int argc, _TCHAR* argv[])
{
    __int8 a=127;
    __int8 b=1;
    __int16 c=b+a;
    __int8  d=b+a;
    printf("c=%d,d=%d\n",c,d);

    return 0;
}

//result is: c=128, d=-128

I don't understand why c==128! My understanding is that in both additions, b+a are still considered addition of 2 signed 8 bit variables. So the result is an overflow i.e. -128. After that, the result is then promoted to 16 bit signed int for the first assignment operation and c should still get a 16 bit -128 value. Is my understanding correct? The c++ standard is a bit difficult to read. Chapter 4 seems talking about integeral promotion but I can't find anything related to this specific example.

Was it helpful?

Solution

My understanding is that in both additions, b+a are still considered addition of 2 signed 8 bit variables. So the result is an overflow i.e. -128.

No, the promotion happens before the + is evaluated, not after it. The addition happens when both a and b are positive. Both numbers are promoted to ints for an addition, added as two positive numbers, and then converted to a 16-bit short. At no point in the process does the result become negative due to an overflow, hence the end result of 128.

Arguably, this makes sense: the behavior of a and b matches that of two numbers in mathematics, making it more intuitive to language practitioners.

OTHER TIPS

It's integral promotion.

1 A prvalue of an integer type other than bool, char16_t, char32_t, or wchar_t whose integer conversion rank (4.13) is less than the rank of int can be converted to a prvalue of type int if int can represent all the values of the source type; otherwise, the source prvalue can be converted to a prvalue of type unsigned int. [§ 4.5]

In this statement

 __int16 c=b+a;

First, all char and short int values are automatically elevated to int. This process is called integral promotion. Next, all operands are converted up to the type of the largest operand, which is called type promotion. [Herbert Schildt]

The values of variables b and a will be promoted to int and then the operation applies on them.

In twos-complement integer representation, a signed value is represented by setting the highest bit. This allows the machine to add and subtract binary integers with the same instructions, regardless of whether the integer is signed.

  a = 127 == 0x7F == 0b01111111
+ b =   1 == 0x01 == 0b00000001
-------------------------------
  c = 128 == 0x80 == 0b10000000
  d =-128 == 0x80 == 0b10000000

The variables c and d may have different types, but different types of integers are merely different interpretations of a single binary value. As you can see above, the binary value fits in 8 bits just fine. Since the standard requires terms of a mathematical expression to be zero- or sign-extended (promoted) to the size of a machine word before any math is done and neither operand will be sign-extended, the result is always 0b10000000 no matter what type the operands are.

In summary, the difference between the results is that, to a 16 bit integer the sign bit is 0b1000000000000000 (which a+b doesn't have), and to an 8 bit integer the sign bit is 0b10000000 (which a+b does have).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top