Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
- Subject: Re: Use of Mac OS X 10.5 / Leopards Garbage Collection Considered Harmful
- From: "Clark Cox" <email@hidden>
- Date: Wed, 6 Feb 2008 08:47:20 -0800
On Feb 6, 2008 1:39 AM, John Engelhart <email@hidden> wrote:
>
> On Feb 5, 2008, at 7:40 AM, Alastair Houghton wrote:
>
> > On 5 Feb 2008, at 00:14, John Engelhart wrote:
> >
> >> I had such high hopes for Cocoa's GC system because once you're
> >> spoiled by GC, it's hard to go back.
> >>
> >> Unfortunately, the 4-5 months of time I've put in on Leopard's GC
> >> system has not been nearly as pleasant. It has been outright
> >> frustrating, and it's reached the point where I consider the system
> >> untenable.
> >
> > Honestly, this point has now been answered over and over.
> >
> > I think it comes down to the fact that you have failed to appreciate
> > that Cocoa GC is designed for easy use with *OBJECTS*. If you're
> > using it with objects, it "just works".
>
> You misunderstand what Objective C is, and how it works. "Objects" is
> synonymous for "Structs".
No, he understands perfectly well. "Structs" are an implementation
detail of "Objects". That is, conceptually, each Objective-C object
*has a* C struct.
> > As far as objects "not being special", they *are* special, in that
> > the compiler generates layout information and method signatures for
> > them.
>
> Read the above, "object" is synonymous for "struct". The "layout" of
> an object is identical to the "layout" of a struct.
Again, that is an implementation detail of the old (32-bit) runtime,
this is not true going forward, and you would be well served to sever
that association in your mental model of Objective-C. Believe me,
Alastair has demonstrated many times over that he understands what he
is saying.
> > or if you absolutely must return a const char * pointer,
> >
> > - (const char *)hexString
> > {
> > return [[NSString stringWithFormat:@"0x%8.8x", myIvar] UTF8String];
> > }
> >
> > which has the benefit of working exactly like -UTF8String. If you
> > *really* wanted, you could mess about with NSAllocateCollectable().
>
> Oh... my...
>
> I could not possibly have asked for a better example of just how easy
> it is to get this wrong.
There is nothing wrong with this example. Since the return value is on
the stack, it is rooted. If you get the result of this function and
expect it to stay around for any length of time, it is your
responsibility to copy it. This is the case without GC and it is still
the case with GC.
> Let those of you who are considering using Leopards GC system use this
> as a warning of how dangerous its use is in practice.
>
> First, understand that my original example, the one in which the GC
> system snatched away the live allocation, did use
> NSAllocateCollectable. Your example, using UTF8String, uses
> NSAllocateCollectable as well. We can infer this by the behavior
> exhibited by the GC system when qualifying pointers that store the
> results from these methods as __strong, which prevents the collector
> from reclaiming the allocation. Thus, by induction, the pointer to
> the buffer that contains the strings text must ultimately come from
> NSAllocateCollectable.
>
> Let's start with NSAllocateCollectable(). The prototype for
> NSAllocateCollectable, from NSZone.h, is as follows:
>
> FOUNDATION_EXPORT void *__strong NSAllocateCollectable(NSUInteger
> size, NSUInteger options) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
>
> NOTE WELL: the __strong qualifier for the pointer.
__strong as a qualifier on a return value is effectively meaningless;
All values on the stack or in a register are implicitly strong. It is
simply there to add information for the human reading it.
> Now, there is no formal grammar of Objective-C 2.0 published, but it
> is a reasonable assumption that "__strong" is in the same group of
> type qualifiers as "const" and "volatile". This makes __strong
> subject to the same ANSI-C rules governing the use of type qualifiers,
> including promotion and assignment rules. Returning to the method
> definition of UTF8String, we find the following in NSString.h:
>
> - (const char *)UTF8String; // Convenience to return null-terminated
> UTF8 representation
>
> Since the pointer that UTF8String returns is provably from
> NSAllocateCollectable,
It may do this now, but that is an implementation detail. Using the
result of UTF8String will work just fine as long as you don't store a
pointer to it for longer than the current context (whether that
context is an autorelease pool in pre-GC or it is the length of time
which the value is on the stack in GC) then you must copy it.
>
> QED, my use of the UTF8String pointer is bug free and legal by ANSI-C
> rules. That this later causes the GC system to reclaim the memory
> pointed to by this pointer is due to a bug in prototype of UTF8String.
> By type promotion rules, the prototype for UTF8String should be:
Your use of UTF8String is counter to the documentation of that method.
>From <http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html#//apple_ref/occ/instm/NSString/UTF8String>:
"The returned C string is automatically freed just as a returned
object would be released; you should copy the C string if it needs to
store it outside of the autorelease context in which the C string is
created."
This is true, regardless of how Apple decides to implement this
method. For instance, it could be a pointer to inline storage within
the NSString instance itself, it could be a pointer into an
autoreleased NSData object, it could be a pointer to an
NSAllocateCollectable-allocated block of memory, etc. Regardless of
how it is implemented, it still behaves as per the contract given you
by UTF8String, you don't need to know any more or any less to use it
properly.
--
Clark S. Cox III
email@hidden
_______________________________________________
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