Topic: Virtual destructors


Author: kitk@mudshark.sunquest.com (Kit Kauffmann)
Date: Thu, 17 Feb 1994 10:23:24
Raw View
To: dml@mozart.esl.com (Denis Lynch)
Subject: Re: VC++ virtual destructors

Thanks for your response. I have had a very productive message exchange with
a C++ compiler author from Liant. I have included some related information with a couple of notes below.

>In comp.lang.c++ article <kitk.251.00118C48@mudshark.sunquest.com>
>you wrote:
>
>A whole lot of stuff....
>
>I'm by no means a supporter of Microsoft, and in particular of
>Microsoft's C++ compiler, which has been the cause of considerable
>blue language around here.
>
>But, I do have a rather pragmatic attitude about life in general, and
>software developed by humans in partiuclar. (Some of the MicroDroids
>are probably human). Here's how I interpret the various things you've
>reported:
>
>1) You declared a Pure Virtual destructor. Sure sounds like that
>makes the class abstract, and the compiler shouldn't let you
>instantiate it. But the C standards are pretty vague about what
>should happen in error cases! I usually find losing sleep over this
>counter productive: if your program is wrong, it's wrong. It would be
>nice if the compiler pointed that out, but once you fix it you won't
>care any more!
>

This I am still sure is a bug and have attempted to report it to MS.

>2) Pure Virtual functions in general don't exist, but it isn't at all
>clear what a Pure Virtual destructor means. As Microsoft pointed out,
>an inherited destructor *will* be called, *always*. There is
>absolutely on way for you to specify "don't call the base class
>destructors." The problem, in more abstract terms, is that the method
>combination rules are different for constructors, destructors, and
>other methods. (Using "method combination" in the CLOS sense). Normal
>methods don't combine -- when you override a member function, the
>overridden function is not called. Constructors combine using
>"before" combination (the inherited ones are called first);
>destructors combine using "after" combination.
>
>This combination anomally is just one of the many bogosities in C++.
>
>Anyway, since destructors *always* have this combination behavior,
>the base classes' destructors will *always* be called. That leads
>directly to Microsoft's contention that the destructor must be
>defined "even though it is pure virtual."

I was mistaken about the fact that pure virtual functions "do not exist".
Declaring a virtual function pure does not mean it does not exist. If you
try do define a virtual function declared "pure" the C++ compiler should
let you. It means that you must invoke it explicitly ( A::~A() ) which may be
useful if a child class virtual function wants to chain to behavior in a
parent class.

Pure virtual destructors present a bit of a problem to the compiler. A
virtual destructor that has been declared pure may still exist. The
compiler cannot tell from the declaration of the class whether the pure
virtual destructor really exists or not.

To be on the safe side MSVC (and others; I believe the "standard" calls for
this behavior) pure virtual destructors "chain" up to parent class
desctructors even if they are pure. This has the unfortunate side affect that
a pure virtual destructor must be declared (given a body) eventhough it has
been declared pure, which is not the case for virtual functions that are not
destructors.

>You go on to ask "so what does it mean to declare the destructor pure
>virtual, then?". Damned good question. Sounds pretty stupid, in fact!
>If *I* had been implementing the compiler and had thought of this
>circumstance, *I* would have done what you suggest: issue an error
>saying "pure virtual destructors are not supported".

The only advantage to pure virtual destructors is that they should make the
class abstract, which may be desirable at times. It does make sense for the
compiler to allow them if they make the class abstract.

>BUT, I have had even worse experience with the WATCOM compiler, which
>positively delights in issuing fatal errors for code that compiles
>and works fine on every other compiler we have access to! So it is
>possible to err in that direction as well.

As a special case the the MSVC (and Liant compiler I am told) issue a
run-time error if a pure virtual destructor is called through the virtual
function table. The only time this is possible is in the constructor of the
child class (before the child class virtual function table is considered to
be fully formed). You would really have to work at it generate this error.
The only error the MSVC compiler should be generating is when I try to
instantiate the class that has not provided a non-pure declaration of the
pure virtual destructor becuase it should still be considered abstract.

>In summary: pure virtual destructors don't make sense. The compiler
>probably should have told you that. Now you know, so don't do it.
>
>On the subject of Microsoft and CompuServe: what a crock of shit.
>There is no way we're going to use CompuServe for anything,
>especially not for getting unhelpful support from Microsoft!
>
>Have a nice day :-)
>
>--
>Denis Lynch    ESL Inc.   Sunnyvale, CA    dml@esl.com
>

Gregory J. Peto
gpeto@mudshark.sunquest.com

Posted by:


Kit Kauffmann   kitk@mudshark.sunquest.com (Internet)
                73363,447 (Compu$erve)
                (801) 277-5790