[gclist] Destructor FAQ

boehm.PARC@xerox.com boehm.PARC@xerox.com
Sat, 16 Mar 1996 11:15:15 PST


I agree this discussion about finalization order and destructors has gotten
much too long.  I'll try to keep this to a couple of points that may have been
misunderstood:

1. Part of my complaint about the Ada terminolgoy is that it reused for
something I think of as existing terminology for something I think is
different, though we seem to disagree on that.  It's clearly too late to fix
this, but I do think it's important to point out the potential for confusion.
There is a fairly thorough discussion of finalization in Cedar (by that name)
in

Rovner, "On Adding Garbage Collection and Runtime Types to a Strongly-Typed,
Statically-Checked, Concurrent Language".  This a July 1985 PARC CSL tech
report, which has been quite frequently cited, I think.  It contains the
statements: "...finalization should be viewed as a performance enhancement.
The correctness of client programs must not depend on finalization".  I think
that's the core of this view, and very different from the C++ view of
destructors.  (Of course, performance enhancements can be important when you
have limited resources available.)

Barry Hayes published a survey of finalization techniques , entitled
"Finalization in the Collector Interface" in the IWMM '92 Proceedings (Springer
LNCS 637).  It discusses a lot of the issues we've been beating on here.

2. It still seems to me that the C++ destructor facility could essentially be
replaced by a convention to call a certain fixed method, say "destruct"
whenever a variable goes out of scope or is deallocated.  This would be
unpleasant, and it's not quite right in the presence of certain other C++
features (which I'm mostly not a fan of), but that's basically the idea.  You
can argue that this breaks abstraction, but I think that effect is fairly
minimal.  Promptness is not an issue.  Timing with respect to other program
pieces is well-defined.  They are (aside from the compiler-temporaries and
static variables, both of which seem to be a mess) called at specific program
points, with well defined ordering between ALL destructors and other program
points.  No concurrency is added.  My picture was that Ada finalizers are
similar, but I'm not an expert there.

All of the above statements are false for collector-based finalization.  Even
if ordering is well-defined to the extent I've been advocating, it's at most a
sparse partial order.  The natural place to execute finalizers is in a new
thread.  There are ways to avoid this added concurrency (and associated
synchronization) with explicit queues, but those issues need to be addressed.
It's impossible to get even weak promptness guarantees without defining
reachability in the language spec, soemthing that's almost never done.

"Maybe we should talk about something else for a while...  ;-) ;-)"

Good plan :-)

Hans