Topic: virtual functions and virtual destructors


Author: jimad@microsoft.com (Jim ADCOCK)
Date: 28 Aug 91 01:10:34 GMT
Raw View
A well know C++ programming error is to have a class without a
virtual destructor and then to delete an instance via a pointer to
a base class rather than via a pointer to the actual class.
[C++ programmers commonly seem to know that this is erroneous, but
they don't also seem to know that its illegal]

Unfortunately, C++ compilers cannot in general diagnose this error.
A new'd derived object can be assigned to a base class pointer in one file
module, and deleted via that base pointer in another file module.
Thus a C++ compiler would have to have program global analysis to
detect these errors in general, or perform runtime type checking.

Therefore, I'd like to suggest for consideration:

If a class has at least one virtual function, and has a destructor,
that destructor be automatically be considered declared virtual.
Everything else to remain the same.

The downside of this [deliberately limited] proposal is that if
a class has virtual function[s] but no destructor, it would still
be illegal [and generally undiagnosable] to delete that object via a base
pointer.  Still, the proposal would remove the majority of the
undiagnosable errors.

Comments?




Author: mat@mole-end.UUCP (Mark A Terribile)
Date: 1 Sep 91 20:25:50 GMT
Raw View
In article <1991Aug28.011034.6690@microsoft.com>, jimad@microsoft.com (Jim ADCOCK) writes:
> A well know C++ programming error is to have a class without a
> virtual destructor and then to delete an instance via a pointer to
> a base class rather than via a pointer to the actual class. ...

> Unfortunately, C++ compilers cannot in general diagnose this error. ...

> Therefore, I'd like to suggest for consideration:
>   If a class has at least one virtual function, and has a destructor,
>   that destructor be automatically be considered declared virtual.
>   Everything else to remain the same.

> The downside ... is that if a class has virtual function[s] but no
> destructor, it would still be illegal ... to delete that object via a base
> pointer.  ...

It's hard to find the right place to issue the warning.  You can issue it
when you see the base class, when you see the derived class, when you see
the `new' on the derived class, when you see the derived class pointer
converted to the base class pointer, etc.   The most restrictive case that
will still work seems to me to be

 When a  new  is performed for an object or array of a derived type
 AND that type inherits virtual functions
 AND that type does not inherit a virtual destructor
  Issue a warning that the object allocated cannot
  safely be destroyed via a base class pointer because ...

The warning might STILL not be right in all cases.
--

 (This man's opinions are his own.)
 From mole-end    Mark Terribile




Author: jimad@microsoft.com (Jim ADCOCK)
Date: 3 Sep 91 19:42:31 GMT
Raw View
In article <643@mole-end.UUCP> mat@mole-end.UUCP (Mark A Terribile) writes:
|In article <1991Aug28.011034.6690@microsoft.com>, jimad@microsoft.com (Jim ADCOCK) writes:
|> A well know C++ programming error is to have a class without a
|> virtual destructor and then to delete an instance via a pointer to
|> a base class rather than via a pointer to the actual class. ...
|
|> Unfortunately, C++ compilers cannot in general diagnose this error. ...
|
|> Therefore, I'd like to suggest for consideration:
|>   If a class has at least one virtual function, and has a destructor,
|>   that destructor be automatically be considered declared virtual.
|>   Everything else to remain the same.
|
|> The downside ... is that if a class has virtual function[s] but no
|> destructor, it would still be illegal ... to delete that object via a base
|> pointer.  ...
|
|It's hard to find the right place to issue the warning.  You can issue it
|when you see the base class, when you see the derived class, when you see
|the `new' on the derived class, when you see the derived class pointer
|converted to the base class pointer, etc.   The most restrictive case that
|will still work seems to me to be

Agreed that its hard to find the right place to issue an *error* message,
thus a compiler cannot generally be expected to diagnose this error.
However, a compiler can issue warnings about what it feels are bad
programming practices wherever it wants.  In particular, I'd want a
compiler to issue a warning at the closing brace of a class with any
virtual functions and without a virtual destructor.

I don't propose that all classes with virtual functions must have
a destructor [which can then be forced to be virtual.]  I mearly propose
that if a class has virtual functions and a destructor, then that destructor
automatically be considered virtual.  This 'fixes' most of the problem,
but can't fix the problem where a programmer insists on having a class
with virtual functions, insists on no destructor, and then deletes such an
object through a pointer type different than the object's actual
exact type.  To fix the problem "everywhere" would require that any
class with a virtual function must have a virtual destructor, and I
think some people might complain about forcing the [compiler generated]
creation of a destructor just so it could be considered virtual.
Anybody have any comments on how these issues tie into how compilers
handle exceptions?