Search code examples
cuint32

2^32 - 1 not part of uint32_t?


Here is the program whose compilation output makes me cry:

#include <inttypes.h>

int main()
{
        uint32_t limit = (1 << 32) - 1; // 2^32 - 1 right?
}

and here is the compilation output:

~/workspace/CCode$ gcc uint32.c 
uint32.c: In function ‘main’:
uint32.c:5:29: warning: left shift count >= width of type [-Wshift-count-overflow]
         uint32_t limit = (1 << 32) - 1; // 2^32 - 1 right?

I thought that (1 << 32) - 1 equals to 2^32 - 1 and that unsigned integers on 32 bits range from 0 to 2^32 - 1, isnt it the case? Where did I go wrong?


Solution

  • You have two errors:

    • 1 is of type int, so you are computing the initial value as an int, not as a uint32_t.
    • As the warning says, shift operators must have their shift argument be less than the width of the type. 1 << 32 is undefined behavior if int is 32 bits or less. (uint32_t)1 << 32 would be undefined as well.

    (also, note that 1 << 31 would be undefined behavior as well, if int is 32 bits, because of overflow)

    Since arithmetic is done modulo 2^32 anyways, an easier way to do this is just

    uint32_t x = -1;
    uint32_t y = (uint32_t)0 - 1; // this way avoids compiler warnings