Search code examples
cbit-manipulation32bit-64bitbit-shift

Does bit-shifting in C only work on blocks of 32-bits


I've been experimenting with C again after a while of not coding, and I have come across something I don't understand regarding bit shifting.

#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void main()
{
    uint64_t x = 0;
    uint64_t testBin = 0b11110000;
    
    x = 1 << testBin;
    
    printf("testBin is %"PRIu64"\nx is %"PRIu64"\n", testBin, x);
    //uint64_t y = 240%32;
    //printf("%"PRIu64 "\n",y);
}

In the above code, x returns 65536, indicating that after bit shifting 240 places the 1 is now sat in position 17 of a 32-bit register, whereas I'd expect it to be at position 49 of a 64-bit register.

I tried the same with unsigned long long types, that did the same thing.

I've tried compiling both with and without the m64 argument, both the same.


Solution

  • In your setup the constant 1 is a 32 bit integer. Thus the expression 1 << testBin operates on 32 bits. You need to use a 64 bit constant to have the expression operate on 64 bits, e.g.:

    x = (uint64_t)1 << testBin;
    

    This does not change the fact that shifting by 240 bits is formally undefined behavior (even though it will probably give the expected result anyway). If testBin is set to 48, the result will be well-defined. Hence the following should be preferred:

    x = (uint64_t)1 << (testBin % 64);