This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Is this a bug for gcc (2.95 and 3.1)?

On Fri, 24 May 2002 03:29:09 +0000 "Mitchell Maggie"
<> 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-declaration member-specificationopt
                  access-specifier : member-specificationopt
                  decl-specifier-seqopt member-declarator-listopt ;
                  function-definition ;opt
                  qualified-id ;
                  member-declarator-list , member-declarator
                  declarator pure-specifieropt
                  declarator constant-initializeropt
                  identifieropt : constant-expression
                   = 0
                   = 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 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

"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.


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.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]