I thought I understood type promotion until today. I ran into a case where an unsigned type was silently promoted to a signed type, causing unexpected results. I know that blaming unexpected results on compiler bugs is one of the first signs that one is losing his grip on reality, but this one has me seriously considering it.
Here’s some code:
byte b = 0x7f; unsigned long u = b << 8; Serial.print("0x7F << 8: "); Serial.println(u, HEX); b = 0x80; u = b << 8; Serial.print("0x80 << 8: "); Serial.println(u, HEX);
which gives me this output:
0x7F << 8: 7F00 0x80 << 8: FFFF8000
I expected b to be promoted to a 16 bit type prior to the left shift, but I didn’t expect the promotion to be from an unsigned type (byte) to a signed type (int). It seems to me that it should have been promoted to an unsigned int.
Of course, if I explicitly cast b to an unsigned type prior to the shift (e.g.
u = (unsigned long)b << 8;, I get the results I expected (i.e. 0x80 << 8: 8000).
Can anyone provide a logical explanation for this unsigned-to-signed promotion, or is that just the way it is?
P.S. I was using the Arduino IDE version 1.0.3 on Mac OS X 10.6.8, and running the code on an Arduino Duemilanove board.