2

I am porting a game from windows to mac.

Here I am stuck with a bunch of linker errors. All errors similar to

Undefined symbols "typeinfo for Baseclass", referenced from: typeinfo for Subclass Subclass.oor "vtable for Aclass referenced from _ZTVNAclass:`

I know that the problem because of missing definition for virtual functions. Its big project and difficult to trace undefined virtual functions. Is their any way to quickly identify undefined virtual functions.

Why cant the compiler identify undefined virtual functions and give a meaningful message instead of cryptic vtable message.

Minimal example :-

class Foo
{  
public:  
  virtual ~Foo(){};  
  virtual void  someMethod();  
};

int main()
{
    Foo  foo;
    return 0;
}

And g++ version 4.2.1 (Apple Inc. build 5664) says:-

Undefined symbols:  
  "vtable for Foo", referenced from:  
      Foo::Foo()   in ccj8yYI2.o  
ld: symbol(s) not found  
collect2: ld returned 1 exit status  
Michael Haidl
  • 5,384
  • 25
  • 43
shakthi
  • 1,597
  • 2
  • 17
  • 29
  • 2
    BEcause if the error messages were easy to read anybody could program and then we would not get the huge salaries that we currently get for being able to decrypt these messages :-) Its a job security thing. – Martin York Sep 07 '10 at 11:29
  • Nothing sensible comes to my mind. Was in the same boat once. Probably only piping the linker output via `c++filt` might help a bit by demangling C++ names. One can also try to peek the symbol tables of `.o` files with the `nm`, somehow filtering the symbols which are defined (and symbols from standard libraries). That would leave you with a list of undefined symbols. 20+ lines in Perl/friends. – Dummy00001 Sep 07 '10 at 11:31

3 Answers3

2

I believe both of these errors mean that the class has virtual functions, but no non-inline virtual functions (easy to do if you come from say a Java background). GCC emits the vtable and (I believe) typeinfo when it emits the first non-inline virtual function in a class. If all your virtual functions are inlined those bits won't be generated.

You'll need to move an inline virtual function to the source file and make it non-inline. The destructor is often a good candidate.

EDIT: I think I misread your question. What about temporarily making your virtual functions non-virtual so that the linker emits missing symbol for that exact function rather than for the vtable? You'd obviously have to remember to revirtualize them later.

EDIT2: When I tried to compile this I got a descriptive error. Can you paste in a minimal example that doesn't?

class Foo
{
public:
    virtual ~Foo();
};

int main()
{
    Foo foo;

    return 0;
}

Output:

Undefined                       first referenced
 symbol                             in file
Foo::~Foo()                         /var/tmp//cc4C2j6B.o
vtable for Foo                      /var/tmp//cc4C2j6B.o
ld: fatal: Symbol referencing errors. No output written to a.out
collect2: ld returned 1 exit status
Mark B
  • 95,107
  • 10
  • 109
  • 188
1

I have encountered a similar issue. In the end I temporarily used clang instead of gcc, which gave much better error messages:

code.cpp:103:20: fatal error: allocating an object of abstract class type 'MyClass'
    instance = new MyClass();
                   ^
code.h:766:16: note: unimplemented pure virtual method 'ForgottenVirtualMethod' in 'MyClass'
  virtual void ForgottenVirtualMethod(int x, int y) = 0;
               ^
1 error generated.
Nick Sonneveld
  • 3,356
  • 6
  • 39
  • 48
0

The first problem usually appears when the class BaseClass is not polymorphic. Make sure it has at least one virtual function (a virtual destructor will do fine).

For the problem with AClass, make sure there has a .cpp file where the virtual methods of Aclass are defined. Make sure they aren't defined in the header file. Sadly there won't be any magical tool for this, at least to my knowledge.

Alexandre C.
  • 55,948
  • 11
  • 128
  • 197