Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!rice!news From: dougm@zamenhof.rice.edu (Doug Moore) Newsgroups: comp.lang.c++ Subject: garbage collection and member functions Message-ID: <1990Dec20.045909.7681@rice.edu> Date: 20 Dec 90 04:59:09 GMT Sender: news@rice.edu (News) Organization: Rice University, Houston Lines: 76 Originator: dougm@zamenhof.rice.edu Please give a thought to the following problem if garbage collection interests you. Otherwise, skip it. I have implemented a mini-Scheme interpreter in C++. Underlying the implementation are the classes Cons and SExpression, where class Cons { SExpression car, cdr; }; and class SExpression { bool isAnAtom; union { Atom *xatom; Cons *xcons; }; }; are the basic representations of the two types. I have implemented the evaluator as a recursive member function of SExpression, and I have lots of other SExpression member functions lying about. The implementation as it stands allocates new Conses regularly, and most of them become garbage; I desire to add a copy-collect garbage collector, to better control memory usage. In order to avoid rewriting all my code, I choose to overload operator new for Conses, so that it copies and collects when a call for a new Cons cannot be immediately satisfied. But this blows my member functions all to hell. Consider one particular context. The evaluator has called for the evaluation of a subexpression and, indirectly, triggered a garbage collection. *This SExpression, the car part of a Cons, is dead. That is, this points to garbage. I can take precautions to make sure that 'this' SExpression is properly copied from the dying Cons space to the new Cons space during the garbage collection, and I do, but 'this' continues to point to something in the dead Cons space. So what can I do? Well, I already add *this to a set of SExpression roots to ensure that it is copied, and I can manage to retrieve its new location after I finish the subexpression evaluation, but then what? Assign the new location to 'this'? I'd rather not use obsolete language features. Don't use the implicit this anymore, but instead explicitly dereference 'that', a pointer that I update after every operation that might have triggered a garbage collection? Well, that idea makes me regret ever using member functions. Or, there's idea that I just tried without success: add a reference to 'this' to a collection of SExpression pointer references updated by the garbage collector. The intent was that the garbage collector would know where 'this' lived ('this' the SExpression *), and update it when *this was copied, so that 'this' would be magically changed to point into the new Cons space after garbage collection. Well, the compiler I used wasn't too fond of references to 'this'. I can certainly solve my problems if I'm willing to abandon member functions and let my memory management implementation spill all over the rest of my code. But then I'd might as well be writing C if I have to do all that. How can I do it elegantly? In case you wondered, this was a school assignment. I was the assigner, not an assignee, and I'm beginning to wonder if it is an appropriate assignment in light of the ugliness of any solution I can find. Thanks for any suggestions you have to offer. Doug Moore (dougm@rice.edu)