When one performs a bitwise operation on an arithmetic type smaller than int
, it is automatically promoted to int
.
std::uint8_t a = 42;
auto b = a | 0x0f;
// b will be of type int
What I haven't been able to determine is what exactly goes on during this promotion, specifically since it is being converted from an unsigned integer to a signed integer. Will the numerical value of a
remain consistent, potentially changing the binary representation? Or will the binary representation remain consistent, potentially resulting in a different numeric value?
Is there a reason that the value would be promoted to int
rather than unsigned int
? The latter wouldn't cause any of this confusion.
Integers have the same value after promotion. The promoted type has to be able to store all of the values of the source type (and probably more) in the first place to be able to do this. In particular, this means that an unsigned value will never become negative after promotion, and if an int
is too small, the promoted type may be unsigned int
. But note that std::uint8_t
will always promote to int
, as it will always be large enough.
When integral promotion happens on signed integers, the "binary representation" of negative values will be sign-extended (more 1s). e.g., with std::int8_t a = -1;
, a & 0b100000000 != 0
, even though the binary representation is just 0b11111111
. But this doesn't happen with unsigned values or signed positive values.
The object representation (when you memcpy to a char array) may change after promotion. This is easy to see in the signed case, but in the unsigned case the bytes may be in a different order due to endianness.
When one performs a bitwise operation on an arithmetic type smaller than int, it is automatically promoted to int.
Correct1. Also, this applies to all arithmetic operations. Not just bitwise operations.
Will the numerical value of a remain consistent
Yes.
potentially changing the binary representation?
Depends a bit on what you expect about the binary representation. Each bit will have the same value as the corresponding original bit in order of significance. But the memory order of bytes will change on little endian systems.
Is there a reason that the value would be promoted to int
Yes. This design choice is explained in ANSI C Rationale quoted in this answer. In short, this allows the value to remain consistent in all promotions.
1Technically, it can on some systems under certain conditions be promoted to unsigned int. More specifically, integer types of lower rank are promoted to int or unsigned int. Char and short are lower rank than int whether they are smaller or same size. When the original value is not representable in int type, it is promoted to unsigned int instead. This can happen on systems where unsigned char and/or unsigned short are same size as int.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With