Piotr
Piotr

Reputation: 5563

Comparing signed and unsigned values in objective-c

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?

Upvotes: 5

Views: 1697

Answers (3)

Guillaume
Guillaume

Reputation: 4361

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.

Upvotes: 4

vishy
vishy

Reputation: 3231

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.

Upvotes: 1

MByD
MByD

Reputation: 137332

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.

Upvotes: 5

Related Questions