Unsigned integer and unsigned char keep the same value, but behave differently?

Why is it that

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

false

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

truly

+3
source share
4 answers

For demonstration purposes, suppose 8-bit char and 32-bit int s.

 unsigned char k=-1; 

k assigned the value 255.

 if(k==-1) 

The left side of the == operator is equal to unsigned char . The right side is int . Since all possible unsigned char values ​​can fit inside an int , the left side is converted to an int (this is done due to the whole promotions given below). This leads to a comparison (255 == -1) , which is incorrect.


 unsigned int k=-1 

k assigned the value 4294967295

 if(k==-1) 

This time, the left side (unsigned int) cannot be placed in int. The standard says that in this case both values ​​are converted to unsigned int. Thus, this leads to a comparison (4294967295 == 4294967295) , which is true.


Relevant quotes from the standard:

Integer shares: (C99, 6.3.1.1p2)

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

Common arithmetic conversions: (6.3.1.8).

[For whole operands] whole actions are performed on both operands. Then, for advanced operands, the following rules apply:
- If both operands are of the same type, then further conversion is not required.
...
- Otherwise, if the operand with an unsigned integer type has a rank greater than or equal to the ranks of the type of another operand, then the operand with an integer type with a sign is converted to the type of an unsigned operand of an integer type ....

+19
source

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

If int can represent all values ​​of the original type (as limited in width for a bit field), the value is converted to int; otherwise, it will be converted to unsigned int. They are called whole promotions .58) All other types are not changed by the integer number of promotions.

In your second case, int cannot represent unsigned int k because it is out of range. Both operands are converted to unsigned int and compare equals.

+1
source

Since there are no sign extensions in a promotion without a subscription, the result will be defrant.

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

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

0
source
 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 with a smaller unsigned type, the result will be truncated in undefined ways, the C standard does not guarantee what will happen.

In the real world, outside the C standard, this is most likely (assuming a 32-bit processor, two add-ons):

-1 - 0xFFFFFFFF. The least significant byte 0xFFFFFFFF will be assigned k . k == 255 . Try printing it with printf("%u") and see for yourself.

In the case of unsigned int k=-1 -1 is still a signed int. But it implicitly (silently) advances to unsigned int when it is stored in k . When you later compare k == -1 , the right side of -1 will again be upgraded to an unsigned type and will be equal to the data stored in k .

0
source

Source: https://habr.com/ru/post/1482963/


All Articles