[Gc] Feature suggestion: gc_cleanup call finalize() first
Boehm, Hans
hans.boehm at hp.com
Wed May 18 14:46:38 PDT 2005
Sorry about the long-delayed reply.
The interface design here was based on "Safe, Efficient
garbage Collection for C++", by Ellis and Detlefs.
(Xerox PARC Report CSL 93-4, among others.)
Given the many discussion about this, and C++ language
changes since then, I'd be inclined to agree that having
finalizers invoke the destructor was probably a mistake.
You give one argument against it. There are other issues
related to concurrency and memory visibility. Finalizers
are a much more complicated (and less frequently needed)
construct than synchronous destructors, and they often
need to obey additional rules. I'm more and more convinced
that we want as clear a distinction between them as possible.
Unfortunately, this interface has been around almost as
long as the above tech report, and I think it's unwise to
just change it. If you want to submit a patch to provide
an alternate class for gc_cleanup that behaves this way,
I'd be favorably inclined to including it in 7.0.
I copied Dave Detlefs, in case he has a different opinion.
Hans
> -----Original Message-----
> From: gc-bounces at napali.hpl.hp.com
> [mailto:gc-bounces at napali.hpl.hp.com] On Behalf Of Neil Toronto
> Sent: Tuesday, April 19, 2005 12:07 AM
> To: gc at napali.hpl.hp.com
> Subject: [Gc] Feature suggestion: gc_cleanup call finalize() first
>
>
> New here, etc. Hello everyone, etc. :)
>
> Great work Hans! I've started using the GC for C++, and I'm looking
> forward to having real reference semantics. As much as I love the STL
> and generic programming, it's just not what I want sometimes.
> This stuff
> is wonderful with a compliant C++ compiler.
>
> Anyway, I had a suggestion for finalization. Here's an example of
> finalization usage, coded naively:
>
> class istream : public gc_cleanup
> {
> public:
> virtual bool is_closed() = 0;
> virtual void close() = 0;
> virtual ~istream()
> {
> if (!is_closed())
> {
> close();
> alert_naughty_user_somehow();
> }
> }
> };
>
> class file_istream : public istream
> {
> public:
> virtual void close()
> {
> printf("Closing open file\n");
> }
> };
>
> The intent of the author is to have the abstract base class call its
> descendant's close() when that descendant gets destroyed.
> It's not going
> to work, though, because the compiler (a good one, anyway)
> will complain
> that istream's destructor calls a virtual method. (A not-so-good
> compiler would build something that throws a fit at run
> time.) Even if
> is_closed() and close() were defined in istream it wouldn't work,
> because inside istream's destructor, file_istream doesn't
> exist anymore.
> (Semantically, anyway. The actual mechanics are an implementation
> detail.) The methods in istream would get called.
>
> If gc_cleanup's static cleanup() method called a virtual method
> finalize() instead of (or as well as) the destructor, it
> could be made
> to work easily:
>
> class istream : public gc_cleanup
> {
> public:
> virtual bool is_closed() = 0;
> virtual void close() = 0;
> virtual void finalize()
> {
> if (!is_closed())
> {
> close();
> alert_naughty_user_somehow();
> }
> }
> };
>
> This works fine - I've tested it with a modified gc_cpp.h. (I added
> about three lines of code.)
>
> There's also a good meta-reason to do it this way, and it's
> one reason
> it's done this way in Java and C#. Destructors chain because it's a
> safe, structured way to deallocate memory. With GC, that's not
> necessary, and calling a virtual finalize() makes more sense. If the
> user wants chaining (which will be almost never), he can call
> the base
> class finalize() manually.
>
> Simple idea, easy implementation. What's not to love?
>
> Neil
>
>
> _______________________________________________
> Gc mailing list
> Gc at linux.hpl.hp.com
> https://www.hpl.hp.com/hosted/linux/mail-archives/gc/
>
More information about the Gc
mailing list