33
votes

Anyone have the expertise to explain when to use NSUInteger and when to use NSInteger?

I had seen Cocoa methods returning NSInteger even in cases where the returned value will always be unsigned.

What is the fundamental reason? Is NSInteger or int strictly limited to if we want to represent negative value?

From NSObjCRuntime.h:

#if __LP64__ || (TARGET_OS_EMBEDDED && !TARGET_OS_IPHONE) || TARGET_OS_WIN32 || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
4

4 Answers

33
votes

You should also be aware of integer conversion rules when dealing with NSUInteger vs. NSInteger:

The following fragment for example returns 0 (false) although you'd expect it to print 1 (true):

NSInteger si = -1;
NSUInteger ui = 1;
printf("%d\n", si < ui);

The reason is that the [si] variable is being implicitly converted to an unsigned int!

See CERT's Secure Coding site for an in-depth discussion around these 'issues' and how to solve them.

21
votes

By default, an integer is assumed to be signed. In other words the compiler assumes that an integer variable will be called upon to store either a negative or positive number. This limits the extent that the range can reach in either direction. For example, a 32-bit int has a range of 4,294,967,295. In practice, because the value could be positive or negative the range is actually −2,147,483,648 to +2,147,483,647. If we know that a variable will never be called upon to store a negative value, we can declare it as unsigned, thereby extending the (positive) range to 0 to +4,294,967,295. So i would say, its okay to use NSInteger when you know that you have a restricted output range. I personally use NSUInteger if I needed to return really big positive only numbers

7
votes

If your method has a suitably restricted output range, you might as well use NSInteger since it's easier to type. As you say, if you need to return negative numbers, NSInteger is the only game in town; I'd only use NSUInteger if I needed to return really big numbers for some reason.

5
votes

I don't know about cocoa specifically, but usually the only disadvantage of signed integers is they usually have half the maximum value as a unsigned int. Such as about 2 billion instead of 4 billion for 32bit systems. Generally this is not a big difference, since if you are dealing with values close to 2 billion, you probably would be just as worried about a 4 billion max in the same case, since it is still putting pretty close to an overflow with just a multiplication of 2 or 3.

Signed integers are usually preferred because the additional flexibility and fact that a signed integer can be used in almost all the scenarios an unsigned integer can plus all the additional scenarios it cannot where a negative is needed.

Unsigned might be preferred if you want to enforce positive only values.