www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/07/28/16:29:57

Message-Id: <m0wsqeo-000S1iC@inti.edu.ar>
Comments: Authenticated sender is <salvador AT natacha DOT inti DOT edu DOT ar>
From: "Salvador Eduardo Tropea (SET)" <salvador AT inti DOT edu DOT ar>
Organization: INTI
To: rwhite AT bellatlantic DOT net, djgpp AT delorie DOT com
Date: Mon, 28 Jul 1997 17:42:06 +0000
MIME-Version: 1.0
Subject: Re: Undefined reference to virtual table

Robert C White Jr <rwhite AT bellatlantic DOT net> wrote:
> Thomas Happ XIII wrote:
> > 
> >         This is an oop c++ problem . . .
> >         I have a class, Map, and a subclass, PicMap.  My Map class has no
> > constructor, three virtual methods, and three non-virtual methods.  My
> > PicMap class has a constructor with several arguments, a destructor,
> > overrides of the three virtual methods in Map, and some of its own
> > methods.  It compiles fine, but when I go to link, it says, ". . . in
> > function Map::Map(void) . . . undefined reference to 'Map virtual table'".
> > First of all, I didn't make a function Map::Map() (or even a function
> > PicMap::PicMap()), but after the error I tried doing the former and it
> > still said the same thing.  It was my understanding that the virtual
> > method table of a subclass is identical to that of the parent class but
> > with its own methods concatenated on the end, so where is this error
> > coming from?
> >                                         Tom
> 
> You haven't *quite* provided enough information.  The things most
> notably are A) does Map have any ancestor classes? and B) does Map use
> any data types with constructors?  C) what compiler are you using?
> 
> My "generic" advice is:
> 
> 1: any class you intend to inherit from and use polymorphically (e.g.
> referencing a PicMap from a Map pointer) where any of the child classes
> will have a destructor, should have *virtual* destructors at the roots
> of the class trees even if that destructor is empty.  This ensures the
> correct destructor is always available to the system.
I sugest it too.
 
> 2: make sure that you re linking in definitions for all the non-pure
> virtual functions in all the ancestor classes.  The "need not be defined
> if never used" rule does not apply, occuring in any virtual table for
> any type constitutes use (e.g. it needs to be resolved by the linker). 
> Most link-time errors involving the virtual tables involves not having a
> definition for a virtual function linked in (usually optimized out by
> hand because of "I never call that" thoughts by the author)
That's a very common problem. In addition I'll say that: Ever provide at least 
a dummy body like this:

virtual int member(void) {};

Most of the time gcc brings this silly error (undefined reference to 'Map 
virtual table') just because some of the functions don't have a declaration. 
And most of the time you don't want to declare the body because they are 
prototypes.
 
> 3: check for any compile-time options that affect the placement of
> virtual tables.  If you are doing multi-file builds whit these options
> inconsistently set all sorts of things may go wrong.
Is strange that somebody makes that.

> 4: if you are doing multi-file "make"s, check that all your dependencies
> are correct.  One old module can really botch things badly.

One very important thing with GCC is that classes with virtual members must be 
declared on headers and at least one member must be in a .cc file. Sometimes if 
you put a base class and a derived class both declared in the same .cc file but 
not in a header gcc will go crazy telling he can't find some members that in 
fact are there. 

Additionally in extreme cases you'll need to use #pragma implementation and #pragma 
interface to get the right error.For example in the case 2 the reported error 
isn't so useful but forcing all with the pragmas you'll know what member is the 
one with no declared body.

SET 
------------------------------------ 0 --------------------------------
Visit my home page: http://www.geocities.com/SiliconValley/Vista/6552/
Salvador Eduardo Tropea (SET). (Electronics Engineer)
Address: Curapaligue 2124, Caseros, 3 de Febrero
Buenos Aires, (1678), ARGENTINA
TE: +(541) 759 0013

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019