If I use 3 << 32, I get the correct result.
If I find the size using sizeof(int), multiply by 8, store the result in a variable, and then use 3 << variable, I get a different result. What am I missing here?
void func()
{
unsigned int sz = sizeof(number) * 8;
unsigned int k = 0;
printf("Value of sz is %u \r\n",sz);
k = (k | (0x3) << sz);
printf("Value of 2_1_MSB is %d \r\n",(3 << 32));
printf("Value of k is %u \r\n",k);
}
On all modern PC-type platforms, int has only 32 bits. Shifting by more than that is undefined. And remember that bit numbers for shifting are zero-based, so for a 32-bit type (like int) then the valid bit range is 0 to 31 (inclusive).
Now for the difference between 3 << 32 and 3 << sz: In the first case the compiler can know that it's shifting more than 32 bits, so it can infer that it will be a 64-bit operation (using long long). In the second case the compiler doesn't know the value of sz because it's a plain variable and not a compile-time constant. Therefore it has to assume that it's a plain int shift and that the value of sz is in range.
The C standard defines shift behavior only for shifts less than the width of the type being shifted (C 2018 6.5.7 3). Shifting a 32-bit int by 32 bits is not defined by the standard.
Differences between 3 << 32 and (0x3) << sz may arise due to the compiler evaluating the former at compile time (perhaps using an operation that shifts all bits out, resulting in zero) and the latter at execution time (perhaps using an instruction that uses only the low five bits of the shift amount, resulting in no shift). Such behaviors may not be relied upon; they may change with optimization, change of target or other compiler configuration, change of compiler version, and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With