Question

Recently I have encountered a problem with comparing signed and unsigned values in objective-c. Here is an example of this problem:

NSArray *array = [NSArray array];
NSLog(@"Count = %d", array.count);
NSLog(@"Count - 2 = %d", array.count - 2);
if (array.count - 2 > 0) {
    NSLog(@"A");
} else {
    NSLog(@"B");
}

At the first glance it seems that the following code should print B. However, when you run it this is what you see:

Count = 0
Count - 2 = -2
A

Now I know that the problem is with comparing signed and unsigned values (array.count is unsigned long).

However, this kind of error is very hard to spot (the code compiles, there is no warning and you may not notice that array.count is unsigned and that it matters). The question is how could I avoid such situations? Is there a safe way of comparing signed and unsigned values?

It is also interesting why NSLog(@"%d", array.count - 2) prints -2?

Was it helpful?

Solution

There is a compiler option, -Wsign-conversion, that warns you about potential signedness problems. In Xcode, you can find it under Implicit Signedness Conversion in the Build Settings.

OTHER TIPS

First, it is not safe to compare signed and unsigned numbers, and in your case array.count - 2 is an unsigned number.

Second, it prints -2 because you used %d which is the formatter for a signed integer. To print unsigned integer use %u.

Here when you

NSLog(@"%d", array.count - 2);

as it is a format specified, your %d becomes an integer, of signed/unsigned. So it prints -2.

Similarly you can make comparisons.

int count = array.count - 2;
if (count > 0) 
{
    NSLog(@"A");
} 
else 
{
    NSLog(@"B");
}

this should print B.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top