gnustep-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Size of NSInteger/NSUInteger/CFIndex


From: Richard Frith-Macdonald
Subject: Re: Size of NSInteger/NSUInteger/CFIndex
Date: Wed, 21 Aug 2013 04:59:50 +0100

On 20 Aug 2013, at 22:34, Stefan Bidi <address@hidden> wrote:

> I'm re-writing the CoreBase string formatting function (printf with %@ 
> support) and while going through the printf(), Apple docs and other sources 
> on the internet I ran across a potential problem with some of the assumptions 
> made when defining these types.
> 
> I understand that despite being very portable, GNUstep isn't made to work on 
> all platforms, but I'm still going to use an unlikely platform as example...
> 
> Anyway, in the Apple docs, they have:
> typedef long NSInteger;
> typedef unsigned long NSUInteger
> typedef long CFIndex;
> 
> Yet, the discussion says:
> When building 32-bit applications, NSInteger is a 32-bit integer. A 64-bit 
> application treats NSInteger as a 64-bit integer.

From all my reading, I think the line immediately above is closest to a 
statement of what the NSInteger/NSUInteger types are for ... to portably 
support the situation where you want an integer big enough to store a pointer, 
when the memory model may (like LP64) have a default integer size which is not 
big enough.

> This is true on LP64 platforms but not on any other platform.  The problem 
> that I see here is that the Apple docs about string formatting say that if 
> you want to format a NSInteger/NSUInteger/CFIndex you should use '%ld' or 
> '%lu'.

they also say you have to cast the value to be a long or unsigned long.
I prefer to stick to the posix standard for this and use the PRIdPTR and 
PRIuPTR macros.
Both formatting options work, both are ugly :-(
IO find the posix macros a bit uglier, but they do have the advantages of being 
a bit shorter than the ld/lu format combined with the cast, and being pretty 
explicit about what the argument type actually is.

> GNUstep, on the other hand, defines these values as intptr_t/uintptr_t, which 
> in my opinion is wrong.  We essentially assume these types are as long as a 
> pointer, which is true if you assume LP64.  However, this assumption is not 
> true for a cross-platform library.

The point about using intptr_t/uintptr_t is precisely that it  doesn't assume 
that a long is the size of a pointer, so it's a portable declaraction for 
NSInteger/NSUInteger.

> Lastly, I was browsing the web and came across this 
> (http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html) where 
> int is 16-bits, long is 32-bits and intptr_t is 16-bits.  I realize AVR is 
> not a target, but I just wanted to use it as another example where long is 
> not equivalent to intptr_t.  And who known, someone might want to use it in 
> the future.
> 
> I would like to suggest typedef'ing NSInteger/NSUInteger/CFIndex as long.  
> That way we can correctly format these integers across all platforms 
> supported by GNUstep.

I think you are understanding this the wrong way round , because you are 
reading the typedefs rather than the documentation.  NSInteger and NSUInteger 
are not supposed to be 'long', they are supposed to be pointer sized;  32bit an 
a 32bit platform and 64bit on a 64bit platform.  If you had a 64bit platform 
with a 128bit long, NSInteger would be 64bit, not 128bit.




reply via email to

[Prev in Thread] Current Thread [Next in Thread]