Some of your descriptions are ok, though I tend to look at things from a different angle.
There's no compiler error or warning because the use of the cast tells the compiler that we think we know what we are doing. In this case what happens is the least significant 8 bits of the integer value 128 are simply stored in the char. That is, the integer 128 is hexadecimal
0x00000080
and the last part
0x80
is stored in the char a, but now it means -128 because the leftmost bit is a 1, showing it is negative.
This is perhaps interesting to consider in terms of the internal representation of the value. When the 8-bit value
0x80
is assigned to a 32-bit signed integer, the negative value is represented by a series of binary ones, in hex it is
0xFFFFFF80
In decimal that still means the same as before, -128.
Here, the same bit pattern as before, hex
0xFFFFFF80
is stored in the variable y. But because y is unsigned, all those one-bits are considered as part of the number which is decimal 4294967168.
|
int z = (unsigned char) a;
|
First the right-hand side is evaluated. As an unsigned char, the value 0x80 means decimal 128. That is the value which is stored in z (0x00000080).
It can be interesting to try out different values using the online converter here:
https://www.mathsisfun.com/binary-decimal-hexadecimal-converter.html
A few comments. Mixing signed and unsigned values in the same statement can be sometimes problematic. Also when using any sort of cast from one type to another there should be some thought given to what may be a risky operation. Stroustrup himself describes c++ casts as ugly, maybe deliberately so in order to remind us that casts are generally best avoided:
http://www.stroustrup.com/bs_faq2.html#static-cast