Search code examples
c++integerones-complement

Assigning max value of smaller integer to a larger integer


Consider the following code:

 uint32_t x = ~uint8_t(0);
 std::cout << x << std::endl;

Now, I fully expected this to output 255, but instead it output 4294967295.

I'm aware of integer promotion in C++, but I can't understand why this would happen. The way I understand it, the expression ~uint8_t(0) should evaluate to 1111 1111 in binary. The ~ operator will then cause the type to be promoted to an int (which I'll assume is 32-bit for the sake of discussion), by sign extending the value to 0000 0000 0000 0000 0000 0000 1111 1111. This promoted value should then be assigned to the lvalue x, resulting in x == 255.

But obviously I'm not understanding this correctly. What am I missing?


Solution

  • The integral promotions are performed on the operand of the unary ~, so the uint8_t(0) is promoted to int and then the ~ is evaluated. It's equivalent to

    ~(int)(uint8_t)0
    

    You can get the maximum value representable by a type using std::numeric_limits<T>::max(); if the type is unsigned, you can also cast -1 to that type:

    uint32_t x = (uint8_t)-1;