Compiler Version: Keil C51 5.0
I experienced some unexpected behaviour with the Keil C51 compiler. I have recreated the issue in the below code snippets.
Case 1: Result of bit shift operator is type casted from uchar (8b) to ulong (32b) correctly
unsigned long tempadcVal; unsigned char data_save_high = 0xA4; unsigned char data_save_low = 0x3F; //The expected 32b value without any information loss //Is loaded into tempadcVal tempadcVal = (data_save_high<<2) + (data_save_low>>6);
Case 2: Result of bit shift operator is not type casted from uint (16b) to ulong (32)
unsigned long modulated; unsigned int value = 0xA43F; modulated = value<<8; //Here we have modulated = 0x00003F00 (Wrong!) //Top 8 bits are wiped out
Is this behaviour by design or perhaps a mistake in the compiler?
Result of bit shift operator is type casted
All explanations so far containing that partial phrase are wrong, because they try to explain the wrong aspect of the actual behaviour.
The issue at hand is not with converting the results of shift operations, but rather with converting their left operands. The bits that get lost do so because the sub-integer operands only get auto-converted up to (unsigned) int, then the shift happens, and the result is still only *unsigned) int. The bit that got lost did so in the shift itself, because (unsigned) int is only 16 bits on this platform.
By the time the result of the shift is converted (again), all the "missing" bits are already gone.
Thank you, Hans-Bernhard Broeker, for pointing that out, I think Bob's answer helped me understand how that statement is incorrect. -Ishank