What is the difference between int and NSInteger? [duplicate]
Asked Answered
C

2

14

Possible Duplicates:
When to use NSInteger vs int?
Why is there is an NSInteger?

Can we use int and NSInteger interchangably? Is there any specific situation to use NSInteger only, instead of using int?

Chronometer answered 19/5, 2011 at 9:46 Comment(1)
Possible duplicate of When to use NSInteger vs int?, How to Convert NSInteger to int, or Why is there an NSInteger, just three among many.Cotta
A
20

Can we use int and NSInteger interchangably?

No. On the LP64 architecture used by Apple, for modern OS X Cocoa, NSInteger is 64 bits wide. This means that if you cast an NSInteger to an int, comparisons against NSNotFound may fail. Here's an example:

NSRange theRange = [@"foo" rangeOfString @"x"];
int location = theRange.location;
if (location == NSNotFound) // comparison is broken due to truncation in line above
{
    // x not in foo
}

In my opinion, you should only use NSInteger where you need to pass a parameter to Cocoa or receive a result from Cocoa and the documentation says the data type is NSInteger. In all other cases:

  • if you don't care about the width of the type, use a C type e.g. int or long.
  • if you do care about the width of the type, use the C99 stdint.h types e.g. int32_t, int64_t.
  • if you need an int guaranteed big enough to hold a pointer, use intptr_t or uintptr_t
Averir answered 19/5, 2011 at 10:8 Comment(1)
Also, if you need the difference between two pointers, you should be using ptrdiff_t, while for the size of an object in memory, size_t is appropriate. And for offsets in files on disk, off_t. All of this is basic C stuff, really.Chiliad
D
2

I would say use standard C99 uintptr_t for pointer sized integers. The definition of NSInteger looks sufficiently cloudy not to be sure it is guaranteed to hold a pointer.

Use NSInteger where the API uses it, if you must. But long will do for all practical purposes.

Looking at NSObjCRunTime, I don't really get the motivation for its current definition. Probably to have an integer type large enough to go up to, for instance, the maximum number of items in an NSArray?

#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
Dittography answered 19/5, 2011 at 10:17 Comment(2)
No, use uintptr_t or intptr_t for pointer-sized integers.Chiliad
Thanks, I'm too C++-98 (and wrong, in this case). Answer adjusted.Dittography

© 2022 - 2024 — McMap. All rights reserved.