On 2010-07-14 17:51:27 -0400, Andrei Alexandrescu <seewebsiteforem...@erdani.org> said:

In my opinion, if you need to clear an object's state, the object itself
should be designed with that in mind (probably offering a clear()
method). The object should be the one to decide if it can become zombie
or not, not the user.

That disables any guarantee that could be reliably made.

(Be sure to read the conclusion at the end before starting a reply.)

It might disable guaranties as to how clear() behaves, but a global clear() that works with everything breaks guarenties (invariants) an object normally offer. A broken invariant normally indicates a broken object. If clear enters the picture, a broken invariant can mean anything.

I'm trying to think of the ramifications with some of my code for examples. Calling clear() on most objects that passes through the D/Objective-C bridge is going to cause a crash. This is because upon construction, those objects keep a pointer to the corresponding Objective-C object. clear() would essentially make that pointer null, as well as reduce the reference count on the Objective-C object. That's "fine", until you call a method. Such a method assume the pointer is not null, and you'll get a segfault. Now, imagine that somewhere in the Cooca framework your object is retained and a call to one of its functions is made when a user click somewhere... it could happen 10 minutes after you called clear().

If clear() was to call the default constructor after calling the constructor, that'd be more acceptable, but even there the behaviour would be quite strange in my case because a D object could become associated with two Objective-C objects (the one before the clear that still thinks it's D counterpart exists, and the new one created by the constructor). So even by calling the destructor *and* the default constructor you could end up breaking invariants of the whole system.

Conclusion:

I'm not really against having a clear() function somewhere, but users of this function should be aware that it might causes problems. I'd put it in the same veins as calling the destructor manually, with the interesting addition to that is that it is memory safe. It might break the immutability of immutable members, might break any system that has some expectations about the lifetime of an object, and might breaks object invariants. Clearly, it's no different than calling the destructor, except that it is memory safe (which is certainly a desirable feature). Advertise it as low-level runtime-level function that is memory-safe and we'll all be fine. (Perhaps it belongs in druntime.)

--
Michel Fortin
michel.for...@michelf.com
http://michelf.com/

Reply via email to