Re: Garbage collector vs variable lifetime
Re: Garbage collector vs variable lifetime
- Subject: Re: Garbage collector vs variable lifetime
- From: Chris Hanson <email@hidden>
- Date: Mon, 09 Jun 2008 03:51:05 -0700
On Jun 9, 2008, at 12:56 AM, John Engelhart wrote:
The semantics are preserved and identical results are calculated
(the 'meaning' is the same). The semantics do not require square()
to literally be called each time.
Yes, that is very clear, because the compiler can have full knowledge
that
In the same sense, there is no requirement that a message literally
be sent each time it appears in the source code as long as it can be
shown that the results would be identical.
This is where you're incorrect. A message MUST be sent, literally,
each time it appears in the source code. Under the Objective-C
semantics it CANNOT be shown at compile time that the results of "the
same" message send will be identical.
For an extreme example, you can replace method definitions at run-
time. This is done in real, production code; it's not hypothetical.
The run time dynamic dispatch nature of objc makes such 'inter-
message dispatch optimizations' much, much harder, especially at
compile time. Ultimately, though, they are fundamentally the same
in terms of optimization.
No, really, they aren't. They are fundamentally different because you
cannot know, from one Planck-time tick of the Universe's clock to the
next, whether such an optimization is possible. (I hope you don't
mind if I also indulge in a bit of hyperbole...)
For example, a whole-program JIT optimizer could theoretically
generate some code that inlines a message dispatch, or even eliminates
it entirely, but it can't change the semantics of the surrounding code
based on the fact that it has done so. (Which is what eliminating the
second [data self]; would do.) Essentially, it must preserve
knowledge that an invocation of [self data] MIGHT be present at that
effective location, because it MIGHT actually have to invoke it after
all if a method is swizzled, a category is loaded, and so on.
If I write
- (void)doSomething:(NSArray *)array {
NSUInteger count1 = [array count];
NSUInteger count2 = [array count];
NSLog(@"%u", count1);
NSLog(@"%u", count2);
}
the compiler can't collapse those into a single invocation of -
count. After all, it could be passed a subclass of NSArray for
whom -count has side-effects. Think about a "thread-safe
array" (as bad as the concept might be) for example.
Well, in the case of your example, you have a bug: You have
statically typed the class to NSArray, not your subclass.
This is not a bug. This is fundamental to how object-oriented
programming works! You should always be able to pass an instance of a
subclass wherever an instance of the superclass is expected.
If one applies the 'attribute only applies to the class it was
specified for' rule:
By statically typing the class to NSArray, you have certified to the
compiler that no other object type will be received as an argument.
When you passed it an object of a different type, even a subclass,
you broke your promise to the compiler.
This is simply wrong.
-- Chris
_______________________________________________
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