when shifting bytes, there are some scenarios that do not seem to make sense, for example
printf("shifted bytes %llx\n",(((long long)1 << 63 ))>>1);
outputs c000000000000000, this does not happen with unsigned long longs or if the initial shift to the left is less than 63. However, since 1 is stored as 0000000000000001 in both signed and unsigned long longs and only bitwise operation are performed, there doesnt seem like there is any reason for the difference,how can something like this happen?
You're shifting a signed value into the sign bit. More formally, the result of the shift is outside the range of values a long long
can store.
In this particular case, the mathematical result of 1<<63
is 263, and a long long
(assuming 64 bit) has a range of -263 to 263-1, so the result is out of range. This triggers undefined behavior in your code.
This is described in section 6.5.8p2 of the C standard regarding the left shift operator:
The result of E1
<<
E2 is E1 left-shifted E2 bit positions; vacated bits are filled with zeros. If E1 has an unsigned type, the value of the result is E1 × 2E2, reduced modulo one more than the maximum value representable in the result type. If E1 has a signed type and nonnegative value, and E1 × 2E2 is representable in the result type, then that is the resulting value; otherwise, the behavior is undefined.