T.g
T.g

Reputation: 169

Signed and unsigned char

Why are two char like signed char and unsigned char with the same value not equal?

char a = 0xfb; 
unsigned char b = 0xfb;
bool f;
f = (a == b); 
cout << f;

In the above code, the value of f is 0.
Why it's so when both a and b have the same value?

Upvotes: 4

Views: 943

Answers (3)

Maxim Egorushkin
Maxim Egorushkin

Reputation: 136515

There are no arithmetic operators that accept integers smaller than int. Hence, both char values get promoted to int first, see integral promotion for full details.

char is signed on your platform, so 0xfb gets promoted to int(-5), whereas unsigned char gets promoted to int(0x000000fb). These two integers do not compare equal.

On the other hand, the standard in [basic.fundamental] requires that all char types occupy the same amount of storage and have the same alignment requirements; that is, they have the same object representation and all bits of the object representation participate in the value representation. Hence, memcmp(&a, &b, 1) == 0 is true.

Upvotes: 8

Bathsheba
Bathsheba

Reputation: 234875

The value of f and, in fact, the behaviour of the program, is implementation-defined.

In C++14 onwards1, for a signed char, and assuming that CHAR_MAX is 127, a will probably be -5. Formally speaking, if char is signed and the number does not fit into a char, then the conversion is implementation-defined or an implementation-defined signal is raised.

b is 251.

For the comparison a == b (and retaining the assumption that char is a narrower type than an int) both arguments are converted to int, with -5 and 251 therefore retained.

And that's false as the numbers are not equal.

Finally, note that on a platform where char, short, and int are all the same size, the result of your code would be true (and the == would be in unsigned types)! The moral of the story: don't mix your types.


1 C++14 dropped 1's complement and signed magnitude signed char.

Upvotes: 6

pergy
pergy

Reputation: 5531

  • Value range for (signed) char is [-128, 127]. (C++14 drops -127 as the lower range).
  • Value range for unsigned char is [0, 255]

What you're trying to assign to both of the variables is 251 in decimal. Since char cannot hold that value you will suffer a value overflow, as the following warning tells you.

warning: overflow in conversion from 'int' to 'char' changes value from '251' to ''\37777777773'' [-Woverflow]

As a result a will probably hold value -5 while b will be 251 and they are indeed not equal.

Upvotes: 4

Related Questions