Topic: abstract or not abstract? inherited destructors?
Author: "Carl Daniel" <cpdaniel@pacbell.net>
Date: Tue, 28 May 2002 03:02:48 GMT Raw View
"MSB" <m.s.b@gmx.net> wrote in message
news:20020527201132.58b8854d.m.s.b@gmx.net...
> The following discussion has come up on the gcc mailing list and I would
> like a comment from someone with in-depth knowledge of the standard. Thank
> you in advance.
An interesting conundrum. The C++ community has tradiltionally taught that
declaring the destructor of a class pure-virtual makes that class abstract.
But what about descendants with implicitly defined destructors?
Looking at every reference in the standard to "pure" and "final overrider",
I find nothing which can be construed to mean that an implicitly defined
destructor would not constitute a "final overrider which is not declared
pure". Therefore, in the example given, B is not abstract.
Comeau agrees that B is not abstract, as does MSVC7. IMO, it's a bug in GCC
3.1.
-cd
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: Michiel.Salters@cmg.nl (Michiel Salters)
Date: Tue, 28 May 2002 17:46:41 GMT Raw View
MSB <m.s.b@gmx.net> wrote in message news:<20020527201132.58b8854d.m.s.b@gmx.net>...
> The following discussion has come up on the gcc mailing list and I would
> like a comment from someone with in-depth knowledge of the standard.
> Thank you in advance.
>
> On Mon, 27 May 2002 19:16:49 +0200 Bernard Dautrevaux
> <Dautrevaux@microprocess.com> wrote:
> >
> > > -----Original Message-----
> > > Subject: Re: Is this a bug for gcc (2.95 and 3.1)?
> > >
> > > On Fri, 24 May 2002 03:29:09 +0000 "Mitchell Maggie" wrote:
> > > > 2:This program will cause gcc3.1 link error ,but passed by gcc2.95
> > > > //code begin
> > > > #include <stdio.h>
> > > > class A {
> > > > public:
> > > > virtual ~A()=0;
> > > > };
> > > > A::~A() { }
> > > > class B:public A { };
> > > >
> > > > int main() {
> > > > B b;
> > > > return 1;
> > > > };
> > > > //code ends
> > > Hmm. This one is more difficult. I believe it is incorrect
> > > according to the standard:
> > >
> > > "10.3 Virtual functions" states in paragraph 8 that
> > >
> > > "8 A virtual function declared in a class shall be defined,
> > > or declared pure in that class, or both;"
> > >
> > > So it is permissible for a pure virtual function to have a definition
> > > (although not inline because the grammar forbids it). However, the
> > > function is still pure virtual even if a definition is
> > > provided
Correct.
> > > And as a consequence in the above example the class A is
> > > abstract, because (same paragraph):
> > >
> > > "A class is abstract
> > > if it has at least one pure virtual function."
Still correct.
> > So far, so good
> > >
> > > Now the important part: Class B is abstract, too, because
> > > (10.4 paragraph 4):
> > >
> > > "4 A class is abstract if it contains or inherits at least
> > > one pure virtual function for which the final overrider
> > > is pure virtual."
> >
> > Here I have a small problem: constructors can be overridden, but not
> > inherited. So Class B does not inhertit the pure virtual destructor...
... and it doesn't contain new pure virtual functions either.
Ergo it is *not* abstract.
( "ctors can be overridden" should've been "dtors...", right? )
> > > Class B does not override the pure virtual destructor so the final
> > > overrider is A::~A(). Nitpickers see "10.3 Virtual
> > > functions" paragraph 2:
> > >
> > > "For convenience we say that any virtual function overrides
> > > itself. Then in any well-formed class, for each virtual
> > > function declared in that class or any of its direct or
> > > indirect base classes there is a unique
> > > final overrider [..]"
> > >
> > > and also paragraph 4
> > >
> > > Even though destructors are not inherited, a destructor in a
> > > derived class overrides a base class destructor declared virtual
> > >
> > > So destructors do really have final overriders.
Yes, but that's not relevant to pure-ness
> > Here I have another problem; even if the destructor is not defined
> > explicitely, it seems that as there is a virtual destructor the
> > compiler must synthesize a destructor, and so there *seems to be*
> > an overriding destructor...
Correct
> > So there is a final overrider for A::~A, which is the implicitely
> > declared and defined B::~B, so B seems NOT to be abstract...
B is not abstract, but that's unrelated to overriders. The members of
B aren't pure, that's why B is concrete.
As 10.4/2 doesn't apply, B b must create a B object and the program
therefore has to link.
Regards,
--
Michiel Salters
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]
Author: MSB <m.s.b@gmx.net>
Date: Tue, 28 May 2002 00:12:24 GMT Raw View
The following discussion has come up on the gcc mailing list and I would
like a comment from someone with in-depth knowledge of the standard. Than=
k
you in advance.
On Mon, 27 May 2002 19:16:49 +0200 Bernard Dautrevaux
<Dautrevaux@microprocess.com> wrote:
>=20
> > -----Original Message-----
> > From: Matthias Benkmann [mailto:matthias@winterdrache.de]
> > Sent: Saturday, May 25, 2002 10:01 PM
> > To: gcc@gcc.gnu.org
> > Subject: Re: Is this a bug for gcc (2.95 and 3.1)?
> >=20
> >=20
> > On Fri, 24 May 2002 03:29:09 +0000 "Mitchell Maggie"
> > <maggie_shh@hotmail.com> wrote:
> >=20
> > > 2:This program will cause gcc3.1 link error ,but passed by gcc2.95
> > > //code begin
> > > #include <stdio.h>
> > > class A
> > > {
> > > public:
> > > virtual ~A()=3D0;
> > > };
> > > A::~A()
> > > {
> > > }
> > > class B:public A
> > > {
> > > };
> > >=20
> > > int main()
> > > {
> > > B b;
> > > return 1;
> > > };
> > > //code ends
> > >=20
> >=20
> >=20
> > Hmm. This one is more difficult. I believe it is incorrect=20
> > according to
> > the standard:
> >=20
> > "10.3 Virtual functions" states in paragraph 8 that
> >=20
> > "8 A virtual function declared in a class shall be defined, =20
> > or declared
> > pure in that class, or both;"
> >=20
> > So it is permissible for a pure virtual function to have a definition
> > (although not inline because the grammar forbids it). However, the
> > function is still pure virtual even if a definition is=20
> > provided, because
> > ("10.4 Abstract classes" paragraph 2)
> >=20
> > "A virtual function is specified pure
> > by using a pure-specifier in the function declaration in
> > the class declaration."
> >=20
> >=20
> > And as a consequence in the above example the class A is=20
> > abstract, because
> > (same paragraph):
> >=20
> > "A class is abstract
> > if it has at least one pure virtual function."
> >=20
>=20
> So far, so good
>=20
> >=20
> > Now the important part: Class B is abstract, too, because=20
> > (10.4 paragraph
> > 4):
> >=20
> > "4 A class is abstract if it contains or inherits at least=20
> > one pure vir-
> > tual function for which the final overrider is pure virtual."
>=20
> Here I have a small problem: constructors can be overridden, but not
> inherited. So Class B does not inhertit the pure virtual destructor...
>=20
> >=20
> >=20
> > Class B does not override the pure virtual destructor so the final
> > overrider is A::~A(). Nitpickers see "10.3 Virtual=20
> > functions" paragraph
> > 2:=20
> >=20
> > "For convenience we say that any virtual function overrides=20
> > itself. Then
> > in any well-formed class, for each virtual function declared in tha=
t
> > class or any of its direct or indirect base classes there is a uniqu=
e
> > final overrider [..]"
> >=20
> > and also paragraph 4=20
> >=20
> > "4 Even though destructors are not inherited, a destructor=20
> > in a derived
> > class overrides a base class destructor declared virtual;"
> >=20
> > So destructors do really have final overriders.
>=20
> Here I have another problem; even if the destructor is not defined
> explicitely, it seems that as there is a virtual destructor the compile=
r
> must synthesize a destructor, and so there *seems to be* an overriding
> destructor...
>=20
> See 12.4 =A73:
> "If a class has no userdeclared destructor, a destructor is
> declared implicitly. An
> "implicitly declared destructor is an inline public member of its
> class."
>=20
> and =A75:
> "An implicitly declared destructor is implicitly defined when it
> is used to destroy=20
> "an object of its class type
>=20
> So there is a final overrider for A::~A, which is the implicitely
> declared and defined B::~B, so B seems NOT to be abstract...
>=20
> > Okay, now that we have established that class B is an=20
> > abstract class, we
> > can look at "10.4 Abstract classes" again and in paragraph 2 we see:
> >=20
> > "no objects of an abstract class can be created
> > except as sub-objects of a class derived from it."
>=20
> If I'm right above this does not apply, and so GCC-3.1 is in error.
>=20
---
[ 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.jamesd.demon.co.uk/csc/faq.html ]