This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

C51 Compiler: Inconsistent Behaviour of Bit Shift Operator (<<)

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?

Parents
  • 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.

Reply
  • 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.

Children