The following code gives the output as "x<=y", though I expected it to be "x>y". Why is it so?
Code:unsigned x=1; signed char y=-1; if (x>y) printf("x>y\n"); else printf("x<=y\n");
The following code gives the output as "x<=y", though I expected it to be "x>y". Why is it so?
Code:unsigned x=1; signed char y=-1; if (x>y) printf("x>y\n"); else printf("x<=y\n");
automatic casting.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
FYI: The compiler cast the y to unsigned! That is the cause of the issue.
I suggest reading up on the rules the compiler follows on size promotions. Note: The rules may be only suggestions.
Tim S.
"...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson
gcc gives the following warning:
The reason for the warning is the strange behaviour when comparing a negative signed value and an unsigned value. The negative value is converted to an unsigned value by "repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type"Code:badunsigned.c:7:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if (x > y) ^
One more than the maximum value of a (4-byte) unsigned is 4294967296, and adding it to -1 gives 4294967295. So the comparison becomes
(In reality it's "as if" 4294967296 is added. Really the 2's complement bit pattern of the signed char value of -1 is sign-extended to 4-bytes and then that bit pattern (all 1's) is simply interpreted as an unsigned value.)Code:if (1 > 4294967295)
So you should always fix that warning. In this case you could:
But really, you need to be questioning why you would be comparing signed and unsigned values in the first place.Code:if ((int)x > y)
From C11 draft:
6.3.1.3 Signed and unsigned integers
1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.
2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type. 60)
3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised.
Last edited by john.c; 04-01-2018 at 08:34 PM.
A little inaccuracy saves tons of explanation. - H.H. Munro