Topic: STL "base" classes with non-virtual destructor
Author: "John Crickett" <john@crickett.co.uk>
Date: Sat, 8 Sep 2001 15:19:21 GMT Raw View
> Especially when we were talking about inlined functinos. If
> the compiler can't inline an empty function it seems a bit
> lame. And if it does inline it, just what does it put other
> than nothing!
There are compilers out there that have this problem, amazingly I've come
across it with a C++ compiler for an embedded chipset... you'd have thought
the manufacturer would have gone balls out to make sure their compiler could
optimise for speed!.
Regards, J
--
John Crickett
e: john@crickett.co.uk
w: http://www.crickett.co.uk
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Colin Rafferty <colin@xemacs.org>
Date: Tue, 4 Sep 2001 23:12:13 GMT Raw View
Piotr Dobrogost wrote:
> According to the November 1997 Draft Standard, the results of deleting an
> object of a derived class through a pointer to an object of its base class
> are undefined if the base class has a non-virtual destructor.
> Defect: The STL design encourages users to publicly inherit from a
> number of classes which do nothing but specify interfaces, and which
> contain non-virtual destructors.
> Proposed resolution:
> When a base class in the standard library is useful only as an interface
> specifier, i.e., when an object of the class will never be directly
> instantiated, specify that the class contains a protected destructor. This
> will prevent deletion through a pointer to the base class without
> performance, or space penalties.
This has a performance penalty, and is completely unnecessary.
First the performance problem: you have just declared a destructor.
This means that every time a unary_function is destroyed, the empty
destructor must be called.
Next, this is unnecessary. Why? Because a pointer to a
unary_function is worthless. There is nothing that you can do with
it. You cannot call methods, you cannot access data. There is no
reason why someone would want this.
--
Colin
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Tue, 4 Sep 2001 23:44:15 GMT Raw View
Colin Rafferty wrote:
> Piotr Dobrogost wrote:
>
>
>>According to the November 1997 Draft Standard, the results of deleting an
>>object of a derived class through a pointer to an object of its base class
>>are undefined if the base class has a non-virtual destructor.
>>
>
>
>>Defect: The STL design encourages users to publicly inherit from a
>>number of classes which do nothing but specify interfaces, and which
>>contain non-virtual destructors.
>>
>
>>Proposed resolution:
>>
>
>>When a base class in the standard library is useful only as an interface
>>specifier, i.e., when an object of the class will never be directly
>>instantiated, specify that the class contains a protected destructor. This
>>will prevent deletion through a pointer to the base class without
>>performance, or space penalties.
>>
>
> This has a performance penalty, and is completely unnecessary.
>
> First the performance problem: you have just declared a destructor.
> This means that every time a unary_function is destroyed, the empty
> destructor must be called.
It would be a truly dreadful compiler which couldn't completely
optimize away a call to a trivial inline destructor. Adding a
trivial, inline, protected destructor should not add execution
time or code size overhead with any compiler which makes even
the most minimal attempt at optimization.
>
> Next, this is unnecessary. Why? Because a pointer to a
> unary_function is worthless. There is nothing that you can do with
> it. You cannot call methods, you cannot access data. There is no
> reason why someone would want this.
But people make mistakes, and this would stop them doing so.
-- James Dennett
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Wed, 5 Sep 2001 04:08:05 CST Raw View
THere ought to be a template for these discussions:
1. Someone proposes that an error-prone construct of limited
utility be disallowed.
2. Objections are raised by people who can conceive of some
obscure use for said construct, even though the number of
misuses of the construct far exceeds the legitimate ones.
3. The proposal is effectively shouted down by loud proponents
of the obscure case.
4. Nothing is done to fix the original problem.
We need a process that makes the language better, not just bigger.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Pete Becker <petebecker@acm.org>
Date: Wed, 5 Sep 2001 16:49:57 GMT Raw View
John Nagle wrote:
>
> THere ought to be a template for these discussions:
>
> 1. Someone proposes that an error-prone construct of limited
> utility be disallowed.
Except that these aren't usually "error-prone," just theoretical sources
of possible errors. When was the last time you called delete on a
pointer to unary_function?
--
Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Wed, 5 Sep 2001 16:56:06 GMT Raw View
John Nagle wrote:
>
> THere ought to be a template for these discussions:
>
> 1. Someone proposes that an error-prone construct of limited
> utility be disallowed.
>
> 2. Objections are raised by people who can conceive of some
> obscure use for said construct, even though the number of
> misuses of the construct far exceeds the legitimate ones.
>
> 3. The proposal is effectively shouted down by loud proponents
> of the obscure case.
>
> 4. Nothing is done to fix the original problem.
Just remember that supporters of the construct have an alternative point
of view on every one of implications you make, and that in any give case
the supporter's view may be more accurate than the opponent's view. The
supporters believe the construct can be misused, but that misuses are
actually much less common than legitimate uses. The supporters believe
that the construct has uses that are much wider and less obscure than
the opponents think they are. That leads to an alternative view of
number 4:
4': Nothing is done to create new problems by "fixing" the original
non-problem.
That version, if correct, is certainly nothing to complain about. In
order to win the argument you have to actually demonstrate that the
opponent's view of the construct is more accurate than the supporter's
view.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Wed, 5 Sep 2001 19:46:24 GMT Raw View
James Dennett <jdennett@acm.org> writes:
[...]
| > First the performance problem: you have just declared a destructor.
| > This means that every time a unary_function is destroyed, the empty
| > destructor must be called.
|
| It would be a truly dreadful compiler which couldn't completely
| optimize away a call to a trivial inline destructor.
Is that statement based on actual facts? My favorite compiler doesn't
do that optimization, but then I don't consider it as a "truly
dreadful compiler". I suspect it not be an exception.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: Wed, 5 Sep 2001 20:07:53 GMT Raw View
Gabriel Dos Reis wrote:
>
> James Dennett <jdennett@acm.org> writes:
>
> [...]
>
> | > First the performance problem: you have just declared a destructor.
> | > This means that every time a unary_function is destroyed, the empty
> | > destructor must be called.
> |
> | It would be a truly dreadful compiler which couldn't completely
> | optimize away a call to a trivial inline destructor.
>
> Is that statement based on actual facts? My favorite compiler doesn't
> do that optimization, but then I don't consider it as a "truly
> dreadful compiler". I suspect it not be an exception.
>
VC++ is trully dreadful, but in release mode while it does generate
code for ~Banana, it doesn't call it. Neither does G++ (not nearly
so deradful), neither does the Sun Forte compiler.
What compiler insists on calling destructors it knows to be null?
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: James Dennett <jdennett@acm.org>
Date: Thu, 6 Sep 2001 04:27:12 GMT Raw View
Gabriel Dos Reis wrote:
> James Dennett <jdennett@acm.org> writes:
>
> [...]
>
> | > First the performance problem: you have just declared a destructor.
> | > This means that every time a unary_function is destroyed, the empty
> | > destructor must be called.
> |
> | It would be a truly dreadful compiler which couldn't completely
> | optimize away a call to a trivial inline destructor.
>
> Is that statement based on actual facts?
No, as "truly dreadful" is a subjective assessment. But a
compiler which can't eliminate calls to most empty methods
isn't, it seems to me, trying very hard.
> My favorite compiler doesn't
> do that optimization, but then I don't consider it as a "truly
> dreadful compiler". I suspect it not be an exception.
I could accept the generation of code for the destructor,
but making a call to an empty, inline destructor sounds
like a QoI problem which could be easily and profitably
fixed.
-- James Dennett
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: John Nagle <nagle@animats.com>
Date: Wed, 5 Sep 2001 23:54:44 CST Raw View
Ron Natalie wrote:
> VC++ is trully dreadful, but in release mode while it does generate
> code for ~Banana, it doesn't call it. Neither does G++ (not nearly
> so deradful), neither does the Sun Forte compiler.
The destructor always has to be generated, even if empty.
It might be called explicitly from another compilation unit.
John Nagle
Animats
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "James Russell Kuyper Jr." <kuyper@wizard.net>
Date: Thu, 6 Sep 2001 17:40:44 GMT Raw View
John Nagle wrote:
>
> Ron Natalie wrote:
> > VC++ is trully dreadful, but in release mode while it does generate
> > code for ~Banana, it doesn't call it. Neither does G++ (not nearly
> > so deradful), neither does the Sun Forte compiler.
>
> The destructor always has to be generated, even if empty.
> It might be called explicitly from another compilation unit.
Such a function would usually be inlined in the class definition, which
makes things a lot easier. An explicit call to the function in any
translation unit where the function definition is visible can be
optimized away. An actual definition of the function need not be
generated unless/until a pointer to it is taken.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@sensor.com>
Date: Thu, 6 Sep 2001 22:42:16 GMT Raw View
> No, as "truly dreadful" is a subjective assessment. But a
> compiler which can't eliminate calls to most empty methods
> isn't, it seems to me, trying very hard.
Especially when we were talking about inlined functinos. If
the compiler can't inline an empty function it seems a bit
lame. And if it does inline it, just what does it put other
than nothing!
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Gabriel Dos Reis <dosreis@cmla.ens-cachan.fr>
Date: Fri, 7 Sep 2001 16:30:42 GMT Raw View
Ron Natalie <ron@sensor.com> writes:
| Gabriel Dos Reis wrote:
| >
| > James Dennett <jdennett@acm.org> writes:
| >
| > [...]
| >
| > | > First the performance problem: you have just declared a destructor.
| > | > This means that every time a unary_function is destroyed, the empty
| > | > destructor must be called.
| > |
| > | It would be a truly dreadful compiler which couldn't completely
| > | optimize away a call to a trivial inline destructor.
| >
| > Is that statement based on actual facts? My favorite compiler doesn't
| > do that optimization, but then I don't consider it as a "truly
| > dreadful compiler". I suspect it not be an exception.
| >
|
| VC++ is trully dreadful, but in release mode while it does generate
| code for ~Banana, it doesn't call it. Neither does G++ (not nearly
| so deradful), neither does the Sun Forte compiler.
|
| What compiler insists on calling destructors it knows to be null?
Hmm, you anticipated my reaction: I didn't exercise VC++ enough.
--
Gabriel Dos Reis, dosreis@cmla.ens-cachan.fr
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "Piotr Dobrogost" <pbc@poczta.onet.pl>
Date: Sun, 2 Sep 2001 04:16:40 GMT Raw View
Hi,
I'm concerned with item 257 from C++ Standard Library Closed Issues List
(Revision 18). We can read this:
"257. STL functional object and iterator inheritance.
According to the November 1997 Draft Standard, the results of deleting an
object of a derived class through a pointer to an object of its base class
are undefined if the base class has a non-virtual destructor. Therefore, it
is potentially dangerous to publicly inherit from such base classes.
Defect:
The STL design encourages users to publicly inherit from a number of classes
which do nothing but specify interfaces, and which contain non-virtual
destructors.
<example using std::unary_function skipped>
Proposed resolution:
When a base class in the standard library is useful only as an interface
specifier, i.e., when an object of the class will never be directly
instantiated, specify that the class contains a protected destructor. This
will prevent deletion through a pointer to the base class without
performance, or space penalties (on any implementation I'm aware of).
Rationale:
The standard is clear as written; this is a request for change, not a defect
in the strict sense. The LWG had several different objections to the
proposed change. One is that it would prevent users from creating objects of
type unary_function and binary_function. Doing so can sometimes be
legitimate, if users want to pass temporaries as traits or tag types in
generic code. "
My question is: Are results of deleting an object of a derived class through
a pointer to an object of its base class _defined_ if the base class has a
non-virtual destructor ? I think they aren't but then item 257 _is_ a
defect.
---
Piotr Dobrogost
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: dietmar_kuehl@yahoo.com (Dietmar Kuehl)
Date: Tue, 4 Sep 2001 17:30:06 GMT Raw View
Hi,
"Piotr Dobrogost" <pbc@poczta.onet.pl> wrote:
> My question is: Are results of deleting an object of a derived class through
> a pointer to an object of its base class _defined_ if the base class has a
> non-virtual destructor ? I think they aren't but then item 257 _is_ a
> defect.
You are right that the results are not defined in the case your described.
However, it is still not a defect that the classes in question don't have
a virtual destructor: In no place are you required to delete objects of this
type through a pointer to the base class if it is a derived object. In fact,
most function objects are never even allocated on the heap and thus are never
released with 'delete'.
The absense of a virtual destructor is just a potential cause for programming
errors which could be removed by making either the destructor virtual or
protected. Both of these approaches were considered to be problematic (one
would imply unnecessary costs and the other would imply unnecessary
restrictions). Since the standard is in no place ambiguous or contradictory
with respect to the destructor of the classes in question, it is not a defect
but rather a change request to improve the library in some form. Such change
requests, although reasonable and well intended, were always rejected as not
a defect and possibly marked for future consideration (I don't know if this
is the case with this particular defect, however).
--
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]