I'm confused by the issue stated in the title. I've been told that in expressions involving both types of variables, signed are converted to/interpreted as unsigned. However, as the following code snippet shows, that isn't always the case.
Code:
unsigned int x = 1;
int y = -20;
printf("Right shift = %x, %d\n", y>>x, y>>x);
printf("If = %x, %d\n", y < x, y < x);
Result:
Right shift = fffffff6, -10
If = 0, 0
The if statement returns the expected 0, -20 being cast to a very large unsigned integer, but the shift expression returns -10, making it evident that arithmetic and not logical shift has taken place. The x has been interpreted as signed rather than the y being interpreted as unsigned.
Could anyone clear this up for me?
In this expression
y>>x
(the C Standard, 6.5.7 Bitwise shift operators)
3 The integer promotions are performed on each of the operands.
That means that as y
has the type int
and x
has the type unsigned int
neither conversion (promotion) occurs. And
- ...The type of the result is that of the promoted left operand.
So the result of the expression has the type int
- the type of the operand y
. As y
has a negative value then
- ...IfE1 has a signed type and a negative value, the resulting value is implementation-defined
As for this expression
y < x
then there is used the usual arithmetic conversions. The boths operands have the same rank so the operand y
of the type int
is converted to the type unsigned int
and its binary representation as an object of the type unsigned int
is greater than the binary representation of the operand x
.
From the C Standard *6.3.1.8 Usual arithmetic conversions)
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.