views:

42

answers:

2

I've found what I think may be a bug with Ivar and Objective-C runtime. I'm using XCode 3.2.1 and associated libraries, developing a 64 bit app on X86_64 (MacBook Pro).

Where I would expect the type encoding for the following "longVal" to be 'l', the Ivar encoding is showing a 'q' (which is a 'long long').

Anyone else seeing this? Simplified code and output follows:

Code:

#import <Foundation/Foundation.h>
#import <objc/runtime.h>
@interface Bug : NSObject
{
    long        longVal;
    long long   longerVal;
}
@property (nonatomic,assign) long longVal;
@property (nonatomic,assign) long long longerVal;
@end

@implementation Bug

@synthesize longVal,longerVal;

@end


int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    unsigned int    ivarCount=0;
    Ivar *ivars= class_copyIvarList([Bug class], &ivarCount);

    for(unsigned int x=0;x<ivarCount;x++) {
        NSLog(@"Name [%@] encoding [%@]",
         [NSString stringWithCString:ivar_getName(ivars[x]) encoding:NSUTF8StringEncoding],
              [NSString stringWithCString:ivar_getTypeEncoding(ivars[x]) encoding:NSUTF8StringEncoding]);
    }

    [pool drain];
    return 0;
}

And here is output from debug console:

This GDB was configured as "x86_64-apple-darwin".tty /dev/ttys000
Loading program into debugger…
sharedlibrary apply-load-rules all
Program loaded.
run
[Switching to process 6048]
Running…
2010-03-17 22:16:29.138 ivarbug[6048:a0f] Name [longVal] encoding [q]
2010-03-17 22:16:29.146 ivarbug[6048:a0f] Name [longerVal] encoding [q]
(gdb) continue

Not a pretty picture!

-- Frank

+2  A: 

It's not a bug. The GCC compiler, under a 64 bits architecture, chooses to represent longs as 64 bit integers. You can check it yourself:

printf("%lu\n", sizeof(long)); // will give "8"

As a reminder, the C standard only defines minimum sizes for integer types. long is only guaranteed to be at least 32 bits.

zneak
zneak, Paul and bbum:Performing a [bug performSelector:@selector(setLongVal:) withObject:[NSNumber numberWithLong:(long)87]];results in:2010-03-18 06:55:48.163 ivarbug[1006:a0f] Bug output after performSelector [longVal [4296082976]]
Frank C.
However, using NSInvocation seems to work for the type. It was using the 'performSelector' that raised my eyebrows to begin with and why I started digging in.
Frank C.
@Frank C.: This is also not a bug. Your property expect a `long` value, and you give them a `NSNumber*` value. You cannot use `performSelector:withObject:` for methods whose argument types aren't `id`; this coincidentally "worked" because `long` and pointers are the same size under the LP64 model. What you have now is most likely the memory address of your NSNumber object. See the doc for `performSelector:withObject:`.
zneak
@zneak - thanks... it's amazing how much I'm glossing over
Frank C.
A: 

Mac OS X, Linux and most other 64-bit operating systems use the LP64 model, where longs and pointers are 64 bits, while ints are 32 bits.

Paul R