cintegercharbyte

signed int and unsigned int are equal based on bytes. but not signed char and unsigned char


Consider the following code:

signed  a = -1;
unsigned b = UINT_MAX;
printf("%d\n", a==b);
signed char c = -1;
unsigned char d = UCHAR_MAX;
printf("%d\n", c==d);

The result will be:

1
0
  1. Why is "==" for char is based on the actual value, and for an int is based on the bit representation?

  1. Consider this code:
signed char a = -1;
unsigned char b = 255;
printf(“%d\n”, a);
printf(“%d\n”, b);
signed  c = -1;
unsigned d = UINT_MAX;
printf(“%d\n”, c);
printf(“%d\n”, d);

The result will be:

-1
255
-1
-1

%d represents char based on actual value but not int


Solution

  • The usual arithmetic conversions will be applied to both the operands of most binary operations on numbers to convert them to a common numeric type before the operation is performed.

    The first step of the usual arithmetic conversions is to apply the integer promotions to the numeric operands. This only affects operands whose integer rank is less than that of the type int (and unsigned int). So it will affect the operand types _Bool, char, signed char, unsigned char, short, and unsigned short, and also bit-fields of various widths. The integer promotions do not change the numeric value of the operand, only the type. If int can represent all values of the original lower rank type (as restricted by the width for a bit-field), then the lower rank value will be converted to int, otherwise the lower rank value will be converted to unsigned int:

    The second step of the usual arithmetic conversions is to convert the promoted operands to a common numeric type. When one operand has type int and the other operand has type unsigned int, the operand of type int will be converted to unsigned int, which will change negative values to large, positive values:


    The second part of OP's question has undefined behavior here:

    unsigned d = UINT_MAX;
    printf(“%d\n”, d);
    

    The printf format specifier %d expects an argument of type int, but an argument of type unsigned int has been supplied, resulting in UB. However, assuming the compiler passes int arguments in the same way as unsigned int arguments, what is likely to happen is that printf will re-interpret the binary representation of the unsigned int value as an int value. Assuming int has a 2's complement representation with no padding bits, the binary representations of (int)-1 and (unsigned int)UINT_MAX will be identical, so printf will output -1 since it is expecting an int. (Reminder: this is undefined behavior.)

    The variadic arguments of the printf call will have the default argument promotions applied. Arguments of type float will be converted to double, and the integer promotions will be applied to arguments of integer type, so: