Reputation: 121
#include<stdio.h>
main()
{
unsigned x=1;
signed char y=-1;
clrscr();
if(x>y)
printf("x>y");
else
printf("x<=y");
}
A signed character has an increased value from -128 to 127. So the expected out put should have been 'x>y', but it isn't. The compiler gives the output - "x<=y". Can you explain why?
Upvotes: 1
Views: 139
Reputation: 4446
When the compiler see comparing an unsigned int with signed int it promote the signed int to unsigned, this mean adding this (in linux box) to the signed one:
#define UINT_MAX (~0U) (defined in this header file : /include/linux/kernel.h)
So now you are comparing UINT_MAX - 1 (UINT_MAX + y) with x, which explain clearly the output.
Edit : to be more clear : on 32 bits machine ---> UINT_MAX = 2 147 483 648 = 2**31
Regards.
Upvotes: 0
Reputation: 8958
Get used to compile with all warnings, i.e. in the case of gcc:
gcc -Wall -Wextra -pedantic source.c -o prog
In your case the flag -Wextra
give the following message:
warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
That doesn't explain why, but it warns you at least ;) .
The explanation is that a signed variable evaluating to -1
is equal to an unsigned evaluating to UINT_MAX
when compared with a relational operator.
The compiler has to do something well defined in that case and this is what people came up with...
Upvotes: 0
Reputation: 23699
C11 §6.8 al3 p95 :
If both of the operands have arithmetic type, the usual arithmetic conversions are performed.
C11 §6.3.1.8 al1 p53 :
[...] 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.
So y
will be promote to an unsigned type, and will be greater than x
(1
).
Upvotes: 2
Reputation: 10541
In your case signed char is converted to unsigned int, thus we are getting a big positive integer instead of -1. Here is an extract from ANSI C standard draft that explains what happens during usual arithmetic conversions that took place.
3.2.1.5 Usual arithmetic conversions
Many binary operators that expect operands of arithmetic type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions: First, if either operand has type long double, the other operand is converted to long double . Otherwise, if either operand has type double, the other operand is converted to double. Otherwise, if either operand has type float, the other operand is converted to float. Otherwise, the integral promotions are performed on both operands. Then the following rules are applied: If either operand has type unsigned long int, the other operand is converted to unsigned long int. Otherwise, if one operand has type long int and the other has type unsigned int, if a long int can represent all values of an unsigned int, the operand of type unsigned int is converted to long int ; if a long int cannot represent all the values of an unsigned int, both operands are converted to unsigned long int. Otherwise, if either operand has type long int, the other operand is converted to long int. Otherwise, if either operand has type unsigned int, the other operand is converted to unsigned int. Otherwise, both operands have type int.
Upvotes: 0
Reputation: 25
in comparison, if one operand is unsigned, then the other operand is implicitly converted into unsigned if its type is signed!
more to found here : Signed/unsigned comparisons
Upvotes: 0
Reputation: 182639
In the comparison the signed char
gets converted to an unsigned int
and thus looks like a really big value. I would expect the compiler to warn you - i.e. something in the lines "comparing signed and unsigned stuff is confusing".
This conversion is mandated under "Relational operators":
If both of the operands have arithmetic type, the usual arithmetic conversions are performed.
Upvotes: 7