On 20 Aug 2013, at 22:34, Stefan Bidi <stefanb...@gmail.com> 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. _______________________________________________ Gnustep-dev mailing list Gnustep-dev@gnu.org https://lists.gnu.org/mailman/listinfo/gnustep-dev