Search code examples
cbitwise-operators

Manually adding a bitmask vs adding a bitwise shift


I am trying to add in a left-wise operator to replace the following:

unsigned long bitmask = 0b10000000000000000000000000000000;
printf("%lu\n", bitmask);

unsigned long bitmask2 = (1 << 31)-1;
printf("%lu\n", bitmask2);

However, the closest I'm able to get is -1. If I try doing (1 << 31), it looks like I get an overflow or something. What would be the proper way to do this?

# in the python shell
>>> 0b10000000000000000000000000000000
2147483648

>>> 1<<31
2147483648

>>> 0b10000000000000000000000000000000 == 1<<31
True

Solution

  • All integer constants like 1 have a type, in this case int. An int is signed and therefore has 31 data bits and 1 sign bit. You cannot left shift data into this sign bit - 1<<31 is a severe undefined behavior bug.

    As a rule of thumb, never mix signed operands with bitwise operators. You can fix the bug by adding a 'u' suffix to the integer constant: 1u << 31. Now the type is unsigned int instead, 32 data bits.

    Please note that the resulting type of a shift operation is that of the left operand. So there is no need to write for example 1u << 31u.