While writing a program for uni, I noticed that
unsigned char byte_to_write_1 = (0xFF << 2) >> 2; ==> 0xFF (wrong)
unsigned char byte_to_write_2 = (0xFF << 2);
byte_to_write_2 = byte_to_write_2 >> 2; ==> 0x3F (correct)
I don't understand what's causing the discrepancy... my best guess is that while modifying a byte with multiple operations on the same line, C "holds onto" the extra bits in a slightly larger datatype until the line is terminated so 0xFF << 2 is held as 11[1111 1100] instead of 1111 1100 so on the same-line shiftback, the result is 1111 1111 instead of 1111 1100.
What causes the difference in results? Thanks in advance...
I first noticed the issue in a larger code project but have been able to recreate the issue using a much more simple program.image of simplified code to showcase problem
The difference between these two code snippets
and
is that in the second code snippet there is used the variable
byte_to_write_2to store the intermediate result of the expression(0xFF << 2). The variable can not hold the full integer result. So the integer result is converted to the typeunsigned charthat can store only one byte.The maximum value that can be stored in an object of the type
unsigned characteris0xFFthat is equal to
255. While the expression0xFF << 2that is equivalent to255 * 4can not fit in an object of the typeunsigned char.In the first code snippet the intermediate result of the expression
(0xFF << 2)has the typeintdue to the integer promotion and can be used without a change in the full expression(0xFF << 2) >> 2.Consider the outputs of these two calls of
printfThey are