From the standard (4.7) it looks like the conversion from int to unsigned int, when they both use the same number of bits, is purely conceptual:
If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2 n where n is the number of bits used to represent the unsigned type). [ Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). — end note ]
So in this direction the conversion preserves the bitmask. I am not sure the standard guarantees the same for the conversion from unsigned int to int (again, assuming the same number of bits are used). The standard here says:
If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.
What does it exactly mean "the destination type" here? For instance 2^32-1 cannot be represented by a 32 bit int. Does that mean that it cannot be represented in the destination type and therefore it cannot be assumed that the bit pattern will stay the same?
int
is the destination type in this case. As you say 2^32-1 cannot be represented so in this case so it is implementation-specific. Although, I've only ever seen it preserve bit patterns.
EDIT: I should add that in the embedded world often whats done when one storage location needs multiple representations that are bit-for-bit identical we often use unions.
so in this case
union FOO {
int32_t signedVal;
uint32_t unsignedVal;
} var;
var
can be accessed as var.signedVal
to get the 32 bits stored as a signed int and var.unsignedVal
to get the 32 bits stored as an unsigned value. In this case bits will be preserved.
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