On Jan 25, 2008, at 9:47 PM, Charlie Dickman wrote: In moving projects from Xcode 2 on Tiger (G4) to Xcode 3 on Leopard (Intel) I have found two cases of code (Objective C) that breaks in Xcode 3 on Leopard (Intel) that works perfectly fine in Xcode 2 on Tiger (G4)...
unsigned u = '\1\0\0\0'; u >>= 8;
results in u equal to '\0\1\0\0' in Xcode 2 on Tiger (G4) but results in '\1\1\0\0' in Xcode 3 on Leopard (Intel).
also
- (NSImageView *) imageViewFrom: (int) n, ... { NSString *silverKey; va_list ap; va_start(ap, n); switch (n) { case 1: silverKey = [NSString stringWithFormat: @"silverImageView%d", va_arg(ap, int)]; break; case 2: silverKey = [NSString stringWithFormat: @"silverImageView%d%d", va_arg(ap, int), va_arg(ap, int)]; break; default: va_end(ap); return nil; } va_end(ap); NSImageView *silverImageView = [silverImageViews objectForKey: silverKey]; return silverImageView; }
when invoked as
[self imageViewFrom: 2, 1, 10];
produces "silverImageView101" for the value of silverKey. Using
case 2: { int _1 = va_arg(ap, int); int _2 = va_arg(ap, int); silverKey = [NSString stringWithFormat: @"silverImageView%d%d", _1, _2]; break; }
produces the expected result of "silverImageView110".
For what it's worth:
1) You can never trust the default size of an implicit type. "unsigned u" can mean different things in different compilers. You have no way to expect what the bit layout is going to be, nor any reasonable expectation of the results of bitwise manipulation. Far better to use a type you know the size of and that doesn't vary according to your target architecture. That's why Apple supplies UInt16, UInt32, UInt64 etc. as base types.
2) You can never trust the order of evaluation of _expression_ subelements. va_arg(ap, int), va_arg(ap, int) are executed in whatever order the compiler feels like at the time. You must break these into separate statements if you want them executed in order.
Chris |