This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: Is this a bug for gcc (2.95 and 3.1)?
- From: Matthias Benkmann <matthias at winterdrache dot de>
- To: gcc at gcc dot gnu dot org
- Date: Sat, 25 May 2002 22:00:46 +0200
- Subject: Re: Is this a bug for gcc (2.95 and 3.1)?
On Fri, 24 May 2002 03:29:09 +0000 "Mitchell Maggie"
<maggie_shh@hotmail.com> wrote:
> HI,All:
> There are two problem about g++.
> OS:
> CYGWIN_NT-5.0 MAGGIE 1.3.10(0.51/3/2) 2002-02-25 11:14 i686 unknown
> 1:
> this program can not pass compilation by gcc2.95 and gcc3.1
>
> //code strat
> #include <stdio.h>
> class A
> {
> public:
> virtual ~A()=0
> {
> };
[NOTE: All ANSI standard quotes below are based on the final working
draft. I don't have a copy of the finished document]
The above program is an error according to the standard. Look at the note
for the example in "10.4 Abstract classes" paragraph 2:
[Note: a function declaration cannot provide both a
pure-specifier and a definition. For example,
struct C {
virtual void f() { }=0; // ill-formed
};
--end note]
For a more formal argument look at the grammar in "9.2 Class members":
member-specification:
member-declaration member-specificationopt
access-specifier : member-specificationopt
member-declaration:
decl-specifier-seqopt member-declarator-listopt ;
function-definition ;opt
qualified-id ;
using-declaration
template-declaration
member-declarator-list:
member-declarator
member-declarator-list , member-declarator
member-declarator:
declarator pure-specifieropt
declarator constant-initializeropt
identifieropt : constant-expression
pure-specifier:
= 0
constant-initializer:
= constant-expression
You can see that "pure-specifier" can not be followed by
"function-definition" and "function-definition" can not be followed by
"pure-specifier". If you're pedantic you will also have to find the rules
for "function-definition" not listed above and you will see that they do
not include "pure-specifier".
> 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, because
("10.4 Abstract classes" paragraph 2)
"A virtual function is specified pure
by using a pure-specifier in the function declaration in
the class declaration."
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."
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 vir-
tual function for which the final overrider is pure virtual."
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
"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.
Okay, now that we have established that class B is an abstract class, we
can look at "10.4 Abstract classes" again and in paragraph 2 we see:
"no objects of an abstract class can be created
except as sub-objects of a class derived from it."
So trying to instantiate an object of class B in the program above is
illegal. So GCC 3.1 is correct if it rejects the program. However, you
said that you got a linker error. In that case it could be argued that the
compilation stage should already issue an error.
MSB
--
The real art of conversation
is not only to say the right thing at the right time,
but also to leave unsaid the wrong thing at the tempting moment.