Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Behavior of integer promotion during bitwise operations

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.

like image 859
John Leuenhagen Avatar asked Sep 01 '20 00:09

John Leuenhagen


2 Answers

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.

like image 108
Artyer Avatar answered Sep 21 '22 13:09

Artyer


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.

like image 38
eerorika Avatar answered Sep 23 '22 13:09

eerorika