Xref: utzoo comp.object:1882 comp.lang.c++:9741 Path: utzoo!attcan!uunet!crdgw1!rpi!zaphod.mps.ohio-state.edu!usc!cs.utexas.edu!milano!cadillac!dsouza From: dsouza@optima.cad.mcc.com (Desmond Dsouza) Newsgroups: comp.object,comp.lang.c++ Subject: Re: C++ and garbage collection Message-ID: Date: 29 Sep 90 01:40:28 GMT Sender: news@cadillac.CAD.MCC.COM Organization: MCC CAD Program, Austin, Texas Lines: 121 In-reply-to: pcg@cs.aber.ac.uk's message of 23 Sep 90 01:07:38 GMT In article pcg@cs.aber.ac.uk (Piercarlo Grandi) writes: > pallas> Now you're not making sense. Either you honor interior pointers > pallas> or you don't. If you do, your collector cannot reclaim anything > ..... > > Sakkinen proposed an example in which a composite object is protected > only by a pointer to an object part of it. The composite object *cannot* > ^^^^^^^^ > be reclaimed manually, because a pointer to one of its parts cannot be > used with operator delete, because it has the wrong type (if nothing > else). You are right about not being able to reclaim the composite object with a pointer to a *data* member (More on this later) I hope this is not too obvious, but: For an object of a class with multiple base classes (C++), would you say that a Base pointer pointing to the Base class portion of the object is pointing to a *part* of it? If so, you certainly can reclaim the entire object manually by calling a *virtual* delete operator on the Base pointer. > As I said, it takes a sophisticated storage reclaimer, manual or > automatic, and a type table at runtime, to be able to reclaim > only the unreachable subojects of a composite object, > leaving the reachable subobjects alone. operator delete is not > even allowed to do it, because it must be presented with a > pointer with the same type and value as one returned by a ^^^^^^^^^^^^^^^^^^^^^^^ > call to operator new. > Piercarlo "Peter" Grandi | ARPA: pcg%uk.ac.aber.cs@nsfnet-relay.ac.uk Sorry, but as long as operator delete is *virtual* in Base, the following is legal. It calls Derived::~Derived, and reclaims a Derived : Derived* dp = new Derived; // "new" returns a Derived* Base* bp = dp; ... delete bp; // delete a Base*: different type, // possibly different value from dp ---------------------------------------- NOW, just for grins, how about this definition of data members: If class A *CONTAINS* a data member of class B, define deletion of the B member as implying deletion of the containing A, provided B::~B is virtual. i.e. destroying a part of an object destroys the object itself. Could this be implemented ? Well, ... : 1. When a B is constructed: *if* it was *contained* in an A, then the dynamic value of B's destructor is the same as the dynamic value of that A's destructor. (This recursive definition accounts for transitive containment). All necessary information is available at compile time, including containment, offsets, etc. The underlying mechanism is much like class derivation, though there will clearly be more versions of B's virtual table -- or equivalent dynamic dispatch mechanism -- due to B being potentially contained (transitively) in several classes. class B { virtual ~B(); }; class A { virtual ~A(); B b; }; B* bp1 = new B; // delete bp1 ==> B::~B B* bp2 = (* new A).b; // delete bp2 ==> A::~A with offsets etc. 2. When an A is constructed: if it was *not* contained in another class, then A's dynamic destructor would be decided by normal class derivation rules. i.e. A::~A if it was an A being created, C::~C if it was constructed as part of a derived class C. class C : public A {}; A* ap = new C; // delete ap ==> C::~C B* bp = &ap->b; // delete bp ==> C::~C Note that since reference data members and constant pointers cannot be re-assigned, the definition of *CONTAINS* could be extended as below to include them, but the implementation might be very difficult. Defns: - B data member: A does contain B - B* data member: can be re-assigned: A does *not* contain B - (B* const) member: re-assign with casts subverts const semantics: A *does* contain B - (const B*) member: re-assign freely: A does *not* contain B - B& data member: cannot be re-assigned: A *does* contain B ---------------------------------------- Personally, I would like a vendor's implementation to provide the information a garbage collector needs to work efficiently. Since there are situations when this is unacceptible it should be a specifiable option, possibly on a per-class basis. Reference counting can get very inefficient very quickly, besides being yet another detail to have to worry about. And manual reclamation, while essential for performance *within* well bounded modules, can seriously complicate re-use from other modules. ...still looking for a compacting, non-conservative gc for c++ :-) Desmond. -- ------------------------------------------------------------------------------- Desmond D'Souza, MCC CAD Program | ARPA: dsouza@mcc.com | Phone: [512] 338-3324 Box 200195, Austin, TX 78720 | UUCP: {uunet,harvard,gatech,pyramid}!cs.utexas.edu!milano!cadillac!dsouza