4

I have heard that shifting into signed bit of an integer, i.e.

int test = INT_MAX;
test = (test<<1) + 1;

is undefined behaviour due to test being greater than INT_MAX. But will this behaviour be encountered in signed short variables, i.e.

short test1 = SHRT_MAX;
test1 = (test1<<1) + 1;

?

At the moment I have not come across any relevant documentation.

EDIT: I know that undefined behaviour will result in the case of integers, but not of short.

Lundin
  • 195,001
  • 40
  • 254
  • 396
  • 2
    @Sander I wouldn't call it a duplicate, because `short`s will be promoted to `int`s before shifting, which adds additional complexity here. – interjay Dec 12 '18 at 15:30
  • @interjay : fair enough - close vote retracted – Sander De Dycker Dec 12 '18 at 15:33
  • 1
    The problem behind the scenes is that the C shift operator is a **'logical shift'**, meaning that it **doesn't care of sign handling**. The promotion between integers follow well known rules that in the specific case, where a `MAX_INT >= MAX_SHORT` should always be true, should guarantee a correct representation of a `short` in an `int`. But when it come to the shift the behavior depends on machine and specific instructions coded by the compiler. I.e. a negative number can become positive right shifted, and the opposite for left shift. But what if CPU uses SAR/SAL arithmetic shifts instead? – Frankie_C Dec 12 '18 at 16:33
  • Kind of related [Why must a short be converted to an int before arithmetic operations in C and C++?](https://stackoverflow.com/q/24371868/1708801) – Shafik Yaghmour Dec 12 '18 at 17:10

1 Answers1

6

When a small integer type is used in most types of expressions, it is promoted to an int (if int can fit all values of the original type), and the expression is then performed on the int.

This gives two possibilites:

  1. On a platform where int is the same size as short, the shift will be undefined behavior because it shifts into the int's sign bit. (More accurately, the reason is that the result cannot be represented as an int). See C11 6.5.7p4.
  2. On a platform where int has more bits than short, the shift itself will be successful (though it can be undefined if you're shifting by more than 1). However, when you assign the result back into a short variable, the value will not be able to be represented as a short. The actual value that will be assigned is implementation-defined. See C11 6.3.1.3p3.
interjay
  • 107,303
  • 21
  • 270
  • 254