Re: Very interesting ordering caveat with NSArray arrayWithObjects:
Re: Very interesting ordering caveat with NSArray arrayWithObjects:
- Subject: Re: Very interesting ordering caveat with NSArray arrayWithObjects:
- From: Gregory Weston <email@hidden>
- Date: Sat, 04 Apr 2009 07:24:42 -0400
Eric Hermanson wrote:
Some (or most) people might be aware of this caveat, but I was not, so
I'll share it.
Consider this code:
NSArray *array = [NSArray arrayWithObjects:[MyCounterClass
newObject], [MyCounterClass newObject], nil];
where [MyCounterClass newObject] is a static method that returns a new
autoreleased instance that simply stores an incrementing int32 counter
in its instance variable, e.g.
self.oid = SomeStaticCounter++; // (or ideally,
OSAtomicIncrement32Barrier(&SomeStaticCounter);
Now, one would expect that the array would contain:
element 1: MyCounterInstance.oid=1
element 2: MyCounterInstance.oid=2
However, this is NOT the case. Either the compiler or the runtime
executes the SECOND call to [MyCounterClass newObject] FIRST, ....
NSArray arrayWithObjects: is of course correctly putting the objects
into the array in the correct natural ordering, but the objects are
CREATED on the stack in the oppose order. Maybe most people knew
that, I did not. So the (or a) workaround is:
MyCounterClass *object1 = [MyCounterClass newObject];
MyCounterClass *object2 = [MyCounterClass newObject];
NSArray *array = [NSArray arrayWithObjects: object1, object2,
nil];
You've discovered the joy of implementation-defined behavior. The
problem is not anything inherent in arrayWithObjects:; it's in the
fact that you're modifying a variable (SomeStaticCounter) twice
between a single pair of sequence points. The elements of an argument
list are not guaranteed to be evaluated in any order. It could go
front to back, or back to front, or alternate left and right from the
outside in.
Note, by the way, that the order in which the arguments are evaluated
has nothing whatsoever to do with the order in which they're put on
the stack. They are not *created* on the stack. They're all evaluated
and then they're pushed in the proper sequence.
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden