This might be a very basic problem, but I couldn't manage to. Here is what I am working with.
#include <stdio.h>
int main(void)
{
char c1, c2;
int s;
c1 = 128;
c2 = -128;
s = sizeof(char);
printf("size of char: %d\n", s);
printf("c1: %x, c2: %x\n", c1, c2);
printf("true or false: %d\n", c1 == c2);
}
The result is like this.
size of char: 1
c1: ffffff80, c2: ffffff80
true or false: 1
i assigned the value 128 to signed(normal) char type, but it didn't overflow.
In additon, c1 and c2 both seems to hold 4bytes, and -128 and 128 are the same value.
How can I understand these facts? I need your help. Thank you very much.
In
c1 = 128;, 128 does not fit in the signed eight-bitcharthat your C implementation uses. 128 is converted tocharper C 2018 6.5.16.1 2: “the value of the right operand is converted to the type of the assignment expression…”The conversion is implementation-defined, per 6.3.1.3 3: “Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.” Your C implementation converted 128, which is 100000002 as an unsigned binary numeral, to −128, which is represented with the same bits when using two’s complement for signed binary. Thus, the result is that
c1contains the value −128.In
printf("c1: %x, c2: %x\n", c1, c2);,c1is converted to anint. This is because the rules for calling functions with...parameters are to apply the default argument promotions to the corresponding arguments, per 6.5.2.2 7: “The default argument promotions are performed on trailing arguments.”The default argument promotions include the integer promotions, per 6.5.2.2 6. When the range of
charis narrower thanint, as it is in most C implementations, the integer promotions convert acharto anint, per 6.3.1.1 2: “If anintcan represent all values of the original type…, the value is converted to anint…”Thus, in
printf("c1: %x, c2: %x\n", c1, c2);, anintvalue of −128 is passed as the second argument. Your C implementation uses 32-bit two’s complement forint, in which −128 is represented with the bits 11111111111111111111111110000000, which we can express in hexadecimal as ffffff80.The format string specifies a conversion using
%x. The proper argument type for%xisunsigned int. However, your C implementation has accepted theintand reinterpreted its bits as anunsigned int. Thus, the bits 11111111111111111111111110000000 are converted to the string “ffffff80”.This explains why “ffffff80” is printed. It is not because
c1has four bytes but because it was converted to a four-byte type before being passed toprintf. Further, the conversion of a negative value to that four-byte type resulted in four bytes with many bits set.Regarding
c1 == c2evaluating to true (1), this is simply becausec1was given the value −128 as explained above, andc2 = -128;also assigns the value −128 toc2, soc1andc2have the same value.