Reputation: 14331
So I ran into a huge issue at work because I had something like this in my code:
int foo = -1;
NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
if (foo > [bar count]){
NSLog(@"Wow, that's messed up.");
} else {
NSLog(@"Rock on!");
}
As you probably already know by me posting this, the output is:
"Wow, that's messed up."
From what I gather, objective C is converting my negative number to a "signed" int and thus, killing my compare.
I saw other posts about this and they all stated what the problem was but none of them suggested any simple solutions to get this comparison to actually work. Also, I'm shocked that there are no compiler warnings, as these are causing serious issues for me.
Upvotes: 10
Views: 2894
Reputation: 2225
Try this
- (IBAction)btnDoSomething:(id)sender {
int foo = -1;
NSArray *bar = [[NSArray alloc] initWithObjects:@"1",@"2",@"3", nil];
if ( foo > (signed)[bar count] ) {
NSLog(@"Wow, that's messed up.");
} else {
NSLog(@"Rock on!");
}
}
Working
If you are comparing two different type of variables then it will implicitly convert data type of both variables to higher type of them.
In this example,
variable foo is of type signed int and array count is of unsigned int,
So it will convert data type of foo to unsigned int
then value of foo will become large number, which is smaller than array count 3.
So in this example you need to down cast array count to signed int.
Issues
When your array count exceeds max limit of signed int then after casting it will rounded back like [ -(negative) max limit -> 0 -> + max limit ] which is unexpected result.
Solution
For more details check this
http://visualcplus.blogspot.in/2006/02/lesson-4-casting-data-types.html
Upvotes: 9
Reputation: 124997
The problem
The problem you're experiencing is that because foo
is a signed integer and -[NSArray count]
returns an unsigned integer, foo
is undergoing implicit type conversion to unsigned integer. See Implicit Type Conversion for more information. Also, there's more information about type conversion rules in C here.
The solution
-[NSArray count]
returns an unsigned value because an array can never have a negative number of elements; the smallest possible value is 0. Comparing an array's count to -1 doesn't make a lot of sense -- the count will always be larger than any negative number (sign problems notwithstanding).
So, the right solution here, and the way to avoid these kinds of problems, is to use a type that matches the return value of -[NSArray count]
, namely NSUInteger
(the U is for unsigned).
Upvotes: 11