Ankit Banerjee
Ankit Banerjee

Reputation: 289

Unsigned integer and unsigned char holding same value yet behaving differently why?

Why is it so that

unsigned char k=-1
if(k==-1)

is false

unsigned int k=-1
if(k==-1)

is true

Upvotes: 3

Views: 564

Answers (4)

interjay
interjay

Reputation: 110146

For the purpose of demonstration let's assume 8-bit chars and 32-bit ints.

unsigned char k=-1;

k is assigned the value 255.

if(k==-1)

The left-hand side of the == operator is an unsigned char. The right-hand side is an int. Since all possible values of an unsigned char can fit inside an int, the left-hand side is converted to an int (this is performed due the the integer promotions, quoted below). This results in the comparison (255 == -1), which is false.


unsigned int k=-1

k is assigned the value 4294967295

if(k==-1)

This time, the left-hand side (an unsigned int) cannot fit within an int. The standard says that in this case, both values are converted to an unsigned int. So this results in the comparison (4294967295 == 4294967295), which is true.


The relevant quotes from the standard:

Integer promotions: (C99, 6.3.1.1p2)

If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int.

Usual arithmetic conversions: (6.3.1.8).

[For integral operands, ] the integer promotions are performed on both operands. Then the following rules are applied to the promoted operands:
- If both operands have the same type, then no further conversion is needed.
...
- 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.
...

Upvotes: 19

autistic
autistic

Reputation: 15642

§6.3.1.1p2 of the C11 standard draft (n1570.pdf):

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.58) All other types are unchanged by the integer promotions.

In your second case, an int can't represent unsigned int k because that's out of range. Both operands end up being converted to unsigned int and compare equal.

Upvotes: 1

Lundin
Lundin

Reputation: 214265

unsigned char k = -1;

-1 is an integer literal of type int, which is equivalent to signed int. When you assign a large signed integer to a smaller unsigned type, the result will get truncated in undefined ways, the C standard does not guarantee what will happen.

In the real world outside the C standard, this is what's most likely (assuming 32-bit CPU, two's complement):

-1 is 0xFFFFFFFF. The least significant byte of 0xFFFFFFFF will get assigned to k. k == 255. Try to print it using printf("%u") and see for yourself.

In the case of unsigned int k=-1, -1 is still a signed int. But it gets implicitly (silently) promoted to an unsigned int when it is stored in k. When you later compare k == -1, the right side -1 will once more get promoted to an unsigned type, and will compare equal with the data stored in k.

Upvotes: 0

Klas Lindbäck
Klas Lindbäck

Reputation: 33273

As there is no sign extension in unsigned promotion the result is defferent.

unsigned char k is promoted from unsigned char (value=255) to int (value=255).

In the case of unsigned int k, -1 is promoted from int (value=-1) to unsigned int (value=2^32-1).

Upvotes: 0

Related Questions