Assigning max value of smaller integer to a larger integer
-
28-09-2019 - |
Question
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;
OTHER TIPS
In your example, the bitwise not operator (~
) is promoting its operand to an int
before it executes. This is then converted to an unsigned int
by the assignment.
Here are some related code samples that make this more clear:
uint8_t y = ~uint8_t(0);
uint32_t x = y;
std::cout << x << std::endl;
255
uint8_t y = uint8_t(0);
int z = ~y;
uint32_t x = z;
std::cout << x << std::endl;
4294967295