0

Signed Short (Signed Int16) Multiplication Explanation?

short ss = -32768; // 0x8000 SHRT_MIN
ss *= (short) -1;
printf ("%d", (int)ss);  // Prints -32768

What are mechanics of how an unsigned short with a value of -32768 times -1 can be itself? My guess is that (int)32768 ---> overflows and wraps back around to -32768 but nowhere here is asking for promotion to integer or any larger datatype.

Looking for the part of the C specification that defines this behavior.

B. Nadolson
  • 2,988
  • 2
  • 20
  • 27
  • Digging around for why it is undefined ... "C/C++ methodology on integer overflow is to provide behaviour that is fastest on the machine you are working on, so on some machines (here assuming 16-bit signed integers):" https://stackoverflow.com/questions/13993047/difference-in-behaviour-of-unsigned-and-signed-integer-when-integer-overflow-occ – B. Nadolson Nov 01 '19 at 04:02

1 Answers1

5

There is no undefined behavior here -- assuming that int is wider than 16 bits.

This:

ss *= (short) -1;

is equivalent to:

ss = ss * (short)-1;

Both operands of * are promoted from short to int (by the integer promotions), and the multiplication is done in type int. It yields the int value 32768 (again, unless INT_MAX == 32767, which is legal but rare in modern non-embedded systems). (C has no arithmetic operations on integer types narrower than int and unsigned int.)

That int value is converted back to short. Unlike arithmetic operations, a conversion of an integer value to a signed integer result, when the value does not fit in the target type, yields an implementation-defined result (or raises an implementation-defined signal, but I don't think any implementations do that).

Converting 32768 to type short will probably yield -32768.

The behavior of signed conversion is specified in N1570 6.3.1.3p3:

Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.

The integer promotions are described in 6.3.1.1p2:

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631