#include
main() {
unsigned int i = 0;
unsigned short s = 0;
int x = -1;
printf("%d %d\n", x>i, x>s);
}
Hint: It's not "0 0".
More info, particularly in the comments. Sometimes it's a wonder that anyone manages to write working code in C. (That anyone can write working C++ is nothing short of miraculous.)
I think John Carmack mentioned this on his twitter feed the other day. Isn't the trick that an unsigned short is automatically changed to be an unsigned int as well or something whacky like that?
ReplyDeleteOr am I looking at it the wrong way, and the int is being changed to an unsigned int?
ReplyDeleteNo directly related, but I had to think of this from the "things that can kill ya" department:
ReplyDeleteFrom C++ 03, 5.8/1: The behavior is undefined if the right operand is negative, or greater than or equal to the length in bits of the promoted left operand.
http://blogs.msdn.com/b/larryosterman/archive/2011/02/11/the-case-of-the-inconsistent-right-shift-results.aspx
So I decided to test this, and in C/C++'s defense, I did get a 'signed/unsigned mismatch' warning when compiling it.
ReplyDeleteNot quite sure I understand the behaviour though, will have to think about this one.
You must not be using gcc:
ReplyDelete[ron@mighty:~]$ cat foo.c
#include
int main() {
unsigned int i = 0;
unsigned short s = 0;
int x = -1;
printf("%d %d %d %d\n", x>i, x>s, i<x, s<x);
return 0;
}
[ron@mighty:~]$ gcc -Wall foo.c
[ron@mighty:~]$
The signed int is converted to unsigned int so (x>i) is true because 11111111 > 00000000 (to however many bits).
ReplyDeleteHowever, the unsigned short is converted to signed int so (x>s) is false because -1 < 0.
There is a sequence of rules to be followed and they make sense altogether.
@miles just out of curiosity, what compiler issues that warning?
ReplyDeleteHopefully, all of them :) You're not supposed to compare signed and unsigned integers.
ReplyDeletethe -Wextra flag gets the warning for me:
ReplyDeleteMYDEV:~$ gcc -Wall -Wextra test.c
test.c: In function ‘main’:
test.c:7: warning: comparison between signed and unsigned integer expressions
test.c:7: warning: comparison between signed and unsigned integer expressions
This is a problem related to (I would say 'invisible') conversions. In this case, for x > i, its converting the signed int to unsigned int.
ReplyDeleteI would say I only know its related to such magic tricks which I would never learn.
Refer to C99 standard, I go to sleep!
******
Now as a corollary, I programmed in C, C++ for first 2 years and thought I was good for nothing where programming was concerned. Then I ran away. I moved to Java. I was still good for nothing. Then I moved to Lisp for the past 2.5 years and I have never encountered such nightmares :-), though Lisp is not perfect; but at least no magic tricks.
I might work at McDonalds than program in C, C++.
******