Subtle problem with virtual keyword that can mislead the unwary...

jeroen dobbelaere xe44 7682 dobbelaj@access.bel.alcatel.be
Fri Mar 27 13:49:00 GMT 1998


Hello,

Skip Montanaro writes:
 > 
 > I'm not really sure this is a bug, but the visible evidence of a
 > programming mistake doesn't do anything to point me at the error.
 > Here's a simple program with a mistake:
 > 
 >     #include <stdio.h>
 > 
 >     class A {
 >     public:
 >       virtual int mf(int) = 0;
 >       virtual ~A();
 >     };
 > 
 >     class B : public A {
 >     public:
 >       virtual int mf(int i) {
 > 	fprintf(stderr, "B::mf() called.\n");
 > 	return i;
 >       }
 >       ~B();
 >     };
 > 
 >     A::~A() {
 >       fprintf(stderr, "A destructor called.\n");
 >     }
 > 
 >     int main(int argc, char **argv) {
 >       B *a;
 > 
 >       a = new B;
 >       a->mf(1);
 >       delete a;
 >     }
 > 
 > egcs (1.00) reports:
 > 
 >     Undefined                       first referenced
 >      symbol                             in file
 >     B virtual table                     /var/tmp/cca000C01.o
 > 
 > g++ 2.8.0 reports the same thing, only uglier:
 > 
 >     Undefined                       first referenced
 >      symbol                             in file
 >     _vt.1B                              /var/tmp/cca000C_1.o
 > 
 > Now, I suspect all the C++ experts reading this are way ahead of me,
 > thinking, "The problem's obvious. He forgot to declare B's destructor
 > virtual."  Sure enough, adding the "virtual" keyword to the

That should not make any difference if the 'virtual' keyword is
used in the base class (as it is).

The main problem seems to me that you declare a destructor for B but
don't define one... But the resulting error message is indeed strange.

I would expect something like : 
undefined symbol B::~B()
at link time...

 > declaration of B::~B() cures the error.

This should not cure the error !

 > 
 > The question I have is: Can't the compiler be a little more helpful
 > here?  Can it at least warn the programmer that the destructor is
 > declared virtual in A but not in its subclass?  (Compiling with -Wall

This can be handy, but is not needed (as said before) : the
baseclass decides if the function will be virtual or not.

 > doesn't cause a peep from the compiler.)
 > 
 > -- 
 > Skip Montanaro (montanaro@crd.ge.com, 518 387 6792)
 > Speaking only for myself, not GE.  (They make me say that...)
 > 
Greetings,
--                              _______ 
Jeroen Dobbelaere            A L\C A T/E L         ALCATEL TELECOM
Software Design Engineer         \   /       Access Systems Division (XE40)
Tel:(32 3)240.76.82       Hi-Speed\ /Solutions      F. Wellesplein 1
Fax: (32 3)240.98.66               V           B-2018 Antwerp (Belgium)



More information about the Gcc-bugs mailing list