Search code examples
cinteger-promotion

If char c = 0x80, why does printf("%d\n", c << 1) output -256?


#include<stdio.h>
int main(void)
{
  char c = 0x80;
  printf("%d\n", c << 1);
  return 0;
}

The output is -256 in this case. If I write c << 0 then the output is -128.

I don't understand the logic behind this code.


Solution

  • Already your starting point is problematic:

    char c = 0x80;
    

    If (as seemingly in your case) char is a signed type, you are assigning the integer constant 128 to a type that is only guaranteed to hold values up to 127. Your compiler then may choose to give you some implementation defined value (-128 in your case I guess) or to issue a range error.

    Then you are doing a left shift on that negative value. This gives undefined behavior. In total you have several implementation defined choices plus undefined behavior that determine the outcome:

    • signedness of char
    • the choice of how to convert 128 to signed char
    • the width of char
    • the sign representation of int (there are three possibilities)
    • the choice on how to implement (or not) left shift on negative int

    It may be a good exercise for you to look up all these case an to see what the different outcomes may be.

    In summary some recommendations:

    • choose an appropriate constant to initialize a variable
    • don't do arithmetic with plain char
    • don't do left shift on signed types