If we have the following code:
char x = -1;
x =~x;
On an x86 platform with MS VS compiler (which partly supports C99) - what happens in detail when it is running?
To my knowledge, the following happens (please correct me if I am wrong):
There are so many things that actually happen - I find it somehow confusing. In particular: Is my understanding of the last implicit conversion (of int to char) correct? What would happen if the assignment's result could not be stored in a char?
Indeed ~x
is an int
type.
The conversion back to char
is well-defined if char
is unsigned
. It's also well-defined, of course, if the value is in the range supported by char
.
If char
is signed
, then the conversion of ~x
to char
is implementation-defined, with the possibility that an implementation defined signal is raised.
In your case, you have a platform with a 2's complement int
and a 2's complement char
, and so ~x
is observed as 0.
Note that MSVC doesn't fully support any C standard, and neither does it claim to.
You are almost correct, but missing out that char
has implementation-defined signedness. It can either be signed or unsigned, depending on compiler.
In either case, the bit pattern for a 8 bit 2's complement char is indeed 0xFF regardless of its signedness. But in case the char
is signed, integer promotion will preserve the sign and you still have value -1
, binary 0xFFFFFFFF on a 32 bit computer. But if char
was unsigned, -1
would have been converted to 255
upon assignment and integer promotion would have given 255
(0x000000FF
). So you'd get a different result.
Regarding integer promotion of ~
, it only has one operator to the right and that one is promoted.
Finally you assign the result back to char
and the outcome will again depend on signedness. You'll have an implicit "lvalue conversion" upon assignment from int
to char
. The result is implementation-defined - most likely you get the least significant byte of the int
.
From this we can learn:
char
for storing integer values or for arithmetic. Use it for storing characters only. Instead, use uint8_t
.unsigned int
or a larger unsigned type.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