user3094631
user3094631

Reputation: 451

c,equality operator on unsigned char and char

why can I get "x==y" when I compare int to unsigned int

then,why can I get "a!=b" when I compare char to unsigned char,although they do have the same bit pattern "0xff"

when applying equality operator,does it take variable type into consideration?

code:

#include <stdio.h>

int main() 
{
    unsigned int x = 0xFFFFFFFF;
    int y = 0xFFFFFFFF;
    printf("unsigned int x = 0xFFFFFFFF;\n");
    printf("int y = 0xFFFFFFFF;\n");
    if (x < 0)
        printf("x < 0\n");
    else
        printf("x > 0\n");
    if (y < 0)
        printf("y < 0\n");
    else
        printf("y > 0\n");
    if(x==y)
        printf("x==y\n\n");
    ///////////-- char --////////////////////////
    unsigned char a = 0xFF;
    char b = 0xFF;    
    printf("unsigned char a = 0xFF\n");
    printf("char b = 0xFF\n");
    if (a < 0)
        printf("a < 0\n");
    else
        printf("a > 0\n");
    if (b < 0)
        printf("b < 0\n");
    else
        printf("b > 0\n");
    if(a==b)
        printf("a==b\n");   
    else
        printf("a!=b\n");

}

output:

unsigned int x = 0xFFFFFFFF;
int y = 0xFFFFFFFF;
x > 0
y < 0
x==y

unsigned char a = 0xFF
char b = 0xFF
a > 0
b < 0
a!=b

Upvotes: 1

Views: 1387

Answers (5)

chux
chux

Reputation: 153338

Step by step: Ignore bit patterns and focus on types and values.

0xFF is a integer constant with the value of 255 and type of int. (C11 §6.4.4.1 5)

unsigned char a = 0xFF assigned 255 to an unsigned char that can represent values [0-255] on your platform. a gets the value of 255 and type unsigned char. 6.3.1.3 1

char b = 0xFF; assigned 255 to an char that, on your platform can represent values [-128 - 127]. The value is converted in an implementation defined manner. In OP's case, 256 is subtracted and b gets the value of -1 and type char. 6.3.1.3 3

When these are compared to 0, the values do not change, yet they are promoted to int. §6.3.1.1 2

Of course, -1 < 0, 255 > 0 and -1 != 255.

Upvotes: 1

Karim Manaouil
Karim Manaouil

Reputation: 1249

From the C11 ISO/IEC 9899:201x standard:

Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

The promotion is applied on int y = 0xFFFFFFFF before comparing with unsigned int x = 0xFFFFFFFF. Promoting int y to unsigned int will keep the value 0xFFFFFFFF, which causes x == y.

On the other hand :

If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int ; otherwise, it is converted to an unsigned int . These are called the integer promotions . All other types are unchanged by the integer promotions. The integer promotions preserve value including sign. As discussed earlier, whether a ‘‘plain’’ char is treated as signed is implementation-defined.

Which means unsigned char a = 0xFF & char b = 0xFF are both converted to signed int before comparison. However converting b will lead to sign extension which means value of b is extended to 0xFFFFFFFF == -1 causing int a = 255 to be greater than int b = -1.

Upvotes: 2

Wang HongQin
Wang HongQin

Reputation: 303

because of promotion.

char or short type will be promoted to int before any comparison.

so

unsigned char a = 0xFF will be promoted to 0x000000FF(255)

char b = 0xFF will be promoted to 0xFFFFFFFF(-1)

they are not equal.

Upvotes: 2

Patrick Sturm
Patrick Sturm

Reputation: 373

A signed integer uses the most significant bit to store a negative number so in hardware-level-logic, you have asked:

IF (-1 != 255){ THEN // ALWAYS RUNS }

Upvotes: -1

thetic
thetic

Reputation: 193

C generally promotes integral values to ints for operations. For unsigned char u = 0xFFu; and signed char s = 0xFF;, in evaluating u == s s is sign-extended and u is not so it is interpreted as 0xFF == -1.

Upvotes: 1

Related Questions