Topic: Public comment on the CD
Author: xmsb@shadow.borland.com (Maurice S. Barnum)
Date: 1995/08/08 Raw View
ajay@lehman.com (Ajay Kamdar) writes:
>In article <3viclo$8cf@sunsystem5.informatik.tu-muenchen.de>,
>Ulf Schuenemann <schuenem@informatik.tu-muenchen.de> wrote:
...
>>
>> The main problem with the proposal is that if you remove the last virtual method,
>> the destructor will loose its implicit virtual, independently whether the virtual
>> was semantically necessary or not.
>>
>> I think this side effect would really surprise programmers. Therefore the
...
>A similar "problem" can be said to exist for the RTTI enhancements voted
>into the CD. The result of a typeid expression is dependent upon whether
>the expression references a polymorphic type or not. Type information for
>the complete object is available via a base class pointer or reference
>only if there exists atleast one virtual function. Remove the last virtual
>function and a program using dynamic casts or typeid will behave
>differently. This adds a level of subtlety to the language, and yet
>RTTI has been accepted in its current form.
There is a major difference here: using typeid or dynamic_cast<>
with a non-polymorphic type can be trivially detected at compile
time.
Locating all points in a large body of source code (that may be
separately compiled) where a virtual destructor is assumed sounds
like a much more difficult problem. Or at least, to this
non-compiler writer...
--xmsb
xmsb@borland.com
xmsb@slaughter.com
Author: ajay@lehman.com (Ajay Kamdar)
Date: 1995/08/07 Raw View
In article <3viclo$8cf@sunsystem5.informatik.tu-muenchen.de>,
Ulf Schuenemann <schuenem@informatik.tu-muenchen.de> wrote:
>
>I've posted Ajay Kamdar's proposal to the german DIN-group (most of them
>from Siemens Nixdorf Informationssysteme AG) at ISO.
>Manfred Lichtmannegger made a good point (new surprises) in his answer:
>
>
> The main problem with the proposal is that if you remove the last virtual method,
> the destructor will loose its implicit virtual, independently whether the virtual
> was semantically necessary or not.
>
> I think this side effect would really surprise programmers. Therefore the
> proposal would reduce the frequency of a common programming error by
> introducing a new subtlety. You reintroducing a new area for this common
> programming error, as it is hard ito trace whether the destructor has lost
> its virtuality by changes in direct or indirect base classes.
>
A similar "problem" can be said to exist for the RTTI enhancements voted
into the CD. The result of a typeid expression is dependent upon whether
the expression references a polymorphic type or not. Type information for
the complete object is available via a base class pointer or reference
only if there exists atleast one virtual function. Remove the last virtual
function and a program using dynamic casts or typeid will behave
differently. This adds a level of subtlety to the language, and yet
RTTI has been accepted in its current form.
Hence the change I have proposed does not add any new subtlety to the
language. The subtlety of a change in program behavior when the last
virtual function is removed already exists and programmers already need
to grapple with the issue. The decisions made for RTTI lay the precedence
for accepting the best possible solution without necessarily coming up
with the perfect answer for both polymorphic and non-polymorphic types.
In this sense, my proposal is very similar in spirit. My proposal would
elminate a common source of programming error, but would not by itself
add a new source of programming error.
>
> MfG Manfred Lichtmannegger
--
Ajay Kamdar | Email: ajay@lehman.com | Standard Disclaimer
Lehman Brothers | Phone: (201) 524-5048 |
Author: ajay@lehman.com (Ajay Kamdar)
Date: 1995/08/03 Raw View
In article <3ver7t$61k@f111.iassf.easams.com.au>,
Rohan LENARD <rjl@f111.iassf.easams.com.au> wrote:
>In article <3v0pam$1lv@jabba.lehman.com>, Ajay Kamdar <ajay@lehman.com> wrote:
>>
>>Make the destructor of a class implicitly virtual if the class has any other
>>virtual functions.
>>
>
>Nice idea, but it really is a quality of compiler implementation issue.
>
>The compiler I use for everyday work gives me quality for code which
>has the problem you describe -
>bug.cc:9: warning: `class Bar' has virtual functions but non-virtual destructor
Yes, as things stand today, this is a quality of compiler implementation
issue. But is there a good reason for it to remain a quality of
implementation issue?
At one point in time in the history of C++, the virtual specifier was
required in the declaration of an overriding function in a derived class
even when the base class function being overridden was already declared
virtual. It could have been left as a quality of implementation issue for
the compiler to warn about a missing virtual specifier in an overriding
function. However, it was considered useful enough to enhance the language to
make the virtual specifier redundant in this case, and to specify the correct
behavior independent of which compiler was being used.
The situation I am addressing is quite analogous. If a class already has other
virtual functions, I know of no reason why anyone would want the destructor
to be non-virtual. There is only one correct thing to do here, and that is
to make the destructor virtual. So why should the language still insist
upon an explicit virtual specifier for the dtor and leave the behavior of
deleting an object of such a class via a pointer to its base class undefined
if the programmer forgets the virtual specifier? The cost of such a mistake
is often high, as many of us can vouch from personal experience.
One of the purposes of enhancements to a language is to make the language
easier to use. The enhancement I have proposed adds substantial value,
does not make the language bigger, makes the language more intuitive and
easier to use, is trivial to implement, requires only a minor modification
to the text of the DWP, has zero impact on object layout, has no unexpected
side effects which break existing programs, has precedence of enhancements
similar in spirit, and does not go against the grain of the design decisions
made for C++ so far.
Often there are good reasons for leaving some things as a quality of
implementation issue. However, I have yet to hear such a good reason for
maintaining status quo in the situation my proposal is addressing.
>There are many things like this in C++. Should we mandate that the compiler
>complains if you don't have a destructor defined at all in a class with a
>virtual function ? Or if you don't define a copy constructor when your
>class manages an object through a pointer ? ...
Unlike the case I am addressing, none of these examples have one obvious
right answer. My proposal is limited to suggesting what is obviously
the only right thing to do.
Regards,
- Ajay
--
Ajay Kamdar | Email: ajay@lehman.com | Standard Disclaimer
Lehman Brothers | Phone: (201) 524-5048 |
Author: John Hickin <hickin@bnr.ca>
Date: 1995/08/03 Raw View
|> At one point in time in the history of C++, the virtual specifier was
|> required in the declaration of an overriding function in a derived class
|> even when the base class function being overridden was already declared
|> virtual.
When was this the case? I have been using different versions of cfront since
1985 and never noticed that type of behavior.
To digress a bit, have a look at the various C++ coding guidelines that have
sprouted all around. They almost universally recommend the explicit use of the
virtual keyword in all derived class function declarations. If your point is
correct (and I am willing to admit that I could be wrong) then the guideline
writers don't seem to regard the current behavior as an *enhancement*.
--
John Hickin Bell-Northern Research, Montreal, Quebec
(514) 765-7924 hickin@bnr.ca
Author: rjl@f111.iassf.easams.com.au (Rohan LENARD)
Date: 1995/07/30 Raw View
In article <3v0pam$1lv@jabba.lehman.com>, Ajay Kamdar <ajay@lehman.com> wrote:
>
>Make the destructor of a class implicitly virtual if the class has any other
>virtual functions.
>
Nice idea, but it really is a quality of compiler implementation issue.
The compiler I use for everyday work gives me quality for code which
has the problem you describe -
bug.cc:9: warning: `class Bar' has virtual functions but non-virtual destructor
There are many things like this in C++. Should we mandate that the compiler
complains if you don't have a destructor defined at all in a class with a
virtual function ? Or if you don't define a copy constructor when your
class manages an object through a pointer ? ...
Regards,
Rohan
--
----------------------------------------------------------------------------
rjl@iassf.easams.com.au | All quotes can be attributed to my automated quote
Rohan Lenard | writing tool. Yours for just $19.95; and if you
+61-2-367-4555 | call now you'll get a free set of steak knives ...
Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/07/31 Raw View
I've posted Ajay Kamdar's proposal to the german DIN-group (most of them
from Siemens Nixdorf Informationssysteme AG) at ISO.
Manfred Lichtmannegger made a good point (new surprises) in his answer:
To make destructors of a polymorphic class virtual is a cheap strategy
as a vtbl-pointer already exists.
But a virtual destructor is only necessary if a non trivial destructor (*)
in some derived class exists (**). This is totally independent whether the
class is polymorphic or not (ignoring the virtual destructor itself :-).
The main problem with the proposal is that if you remove the last virtual method,
the destructor will loose its implicit virtual, independently whether the virtual
was semantically necessary or not.
I think this side effect would really surprise programmers. Therefore the
proposal would reduce the frequency of a common programming error by
introducing a new subtlety. You reintroducing a new area for this common
programming error, as it is hard ito trace whether the destructor has lost
its virtuality by changes in direct or indirect base classes.
(*) for instance deleting some pointer members
(**) this condition is not locally deceidable. Therefore the best would be
to define every destructor virtual, but in some cases the vtbl-ptr would
be to expensive.
MfG Manfred Lichtmannegger
--
"Autobahnen sind elementar auch in der Oberhoheit der Laender"
Bundeskanzler Kohl zur Zukunft der Datenautobahnen
email: Manfred.Lichtmannegger@mch.sni.de
[ address and telephone eleded ]
Ulf Schuenemann
--------------------------------------------------------------------
Ulf Sch nemann
Fakult t f r Informatik, Technische Universit t M nchen, Germany.
email: schuenem@informatik.tu-muenchen.de
WWW: http://www.informatik.tu-muenchen.de/cgi-bin/nph-gateway/hphalle2/~schuenem/index.html
...there is only one way to "skin a C+@"...:) -- Jim Fleming
Author: schuenem@informatik.tu-muenchen.de (Ulf Schuenemann)
Date: 1995/07/28 Raw View
In article <3v0pam$1lv@jabba.lehman.com>, ajay@lehman.com (Ajay Kamdar) writes:
[..]
|> Proposal
|> ========
|>
|> Make the destructor of a class implicitly virtual if the class has any other
|> virtual functions.
|>
[..]
I like that. Sounds _very_ usefull from the software quality/engeneering
point of view.
[ The alternative that the dtor of such a class is required to be _explicitly_
declared virtual - as implemented as a warning by some compilers -
is much less convincing, coz
- if there was no dtor until now, you'd had to supply a useless empty one
- virtuallity already is implicit sometimes (see overriding virtual members):
only the intruder has to declare a member virtual, all descendants
inherit the virtuallity.
]
Ulf Schuenemann
--------------------------------------------------------------------
Ulf Sch nemann
Fakult t f r Informatik, Technische Universit t M nchen, Germany.
email: schuenem@informatik.tu-muenchen.de
WWW: http://www.informatik.tu-muenchen.de/cgi-bin/nph-gateway/hphalle2/~schuenem/index.html
...there is only one way to "skin a C+@"...:) -- Jim Fleming
Author: ajay@lehman.com (Ajay Kamdar)
Date: 1995/07/24 Raw View
I missed the boat (July 6) for submitting the following comment for
consideration at the July 9 meeting, but did send it out today just before
the July 25 deadline.
Here's the text of the comment for your perusal.
Proposal
========
Make the destructor of a class implicitly virtual if the class has any other
virtual functions.
Required modifications to the text of the CD
============================================
[ Addition to existing text is marked with ^^^^^]
12.4 Destructors [class.dtor]
6. Destructors are not inherited. A destructor can be declared virtual
or pure virtual; a destructor is implicitly virtual if the class has
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
any other virtual functions; if any objects of that class ...
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Discussion
==========
*) Forgetting to make the destructor of a polymorphic class virtual is a
common mistake made both by inexperienced and experienced C++ programmers.
This makes it harder to use the language, and the resulting problems are
often difficult to debug and fix. Accepting this proposal eliminate an
unnecessary source of errors.
*) There are no backward compatibility issues to worry about. The behavior
of deleting an object using a pointer to a static type without a virtual
destructor is currently specified to be undefined if the dynamic type of
the object is different from the static type. [expr.delete] [5.3.5.3]
*) There is no reason for wanting *not* to execute all the appropriate
destructors.
*) There would be no change to the layout of an object because the destructor
would be made implicitly virtual only if the class had at least one other
virtual function.
*) A (positive) side effect of the change would be that existing erroneous
code which currently has undefined behavior would start behaving properly.
*) It would be very easy to modify compilers to implement the new behavior.
--
Ajay Kamdar | Email: ajay@lehman.com | Standard Disclaimer
Lehman Brothers | Phone: (201) 524-5048 |