Fri, 11 Apr 1997 10:15:18 -0500
Fergus Henderson wrote:
> Carl Bruggeman wrote:
> > Hans Boehm wrote:
> > > The default behavior should be to err on the side of safety. In the
> > > presence of topologically ordered finalization, you (on rare occasions)
> > > do need a mechanism that corresponds to explicitly clearing pointers.
> > > That allows you to use other orderings when you have to.
> > I believe that this confirms that topological ordering is not always
> > the correct order. You explicitly clear pointers to change the order
> > of finalization (requiring global knowledge of the dependencies on the
> > part of the programmer to do so), while we advocate using multiple
> > guardian queues to handle finalization dependencies.
> Explicitly using weak pointers or "weak-for-finalization" pointers
> (pointers which are ignored when determining finalization order) does
> not require global knowledge of the dependencies. To declare a
> particular pointer which is a member of type A as "weak-for-finalization",
> all you need to know is that the finalizer for type A will still work
> if that pointer has been cleared because the object it points to has
> already been finalized. This can be determined by looking at the code
> for A's finalizer.
This is precisely my point. The programmer must know that the object
pointed at by the weak-for-finalization pointer, __and__ all the
objects pointed at by that object, and all the objects pointed at by
those objects, etc. don't depend on A. For simple cases (probably
the vast majority), only the code for A needs to be inspected. For
more complex cases (such as a cycle of dependencies or chains where
the finalizer code may be more complex) the programmer must bring
global semantic knowledge to the problem.
All I am arguing is that _in some cases_ the programmer must have
global knowledge of the program's finalization dependencies to know
which pointers must be weak-for-finalization, just as _in some cases_
the programmer must know about the program's finalization dependencies
to know the order in which to query guardians. When finalization
dependencies are simple enough, both approaches have simple interfaces
that requires little (guardians) or no (topological) work. When the
programmer is in error bringing global knowledge to the problem, such
as breaking a cycle or chain in the wrong place with a weak pointer,
memory can be deallocated incorrectly (or other "dangerous" things can
occur) using either approach. I think guardians provide a much
better approach when more control is needed, but that topological
ordering provides an acceptable ordering most of the time without
requiring anything of the programmer. Obviously, I prefer the former
while you and others prefer the latter.
Carl Bruggeman -- email@example.com -- Phone: (817) 272-3600 Fax: 272-3784
Computer Science and Engineering Department -- University of Texas at Arlington