Tuesday, June 8, 2010

Error message: Undefined reference to vtable

Another common error message when you compile NS2 would look like this

Book/otcl.o:otcl.cc:(.text+0x8c): undefined reference to `vtable for MyObject'
collect2: ld returned 1 exit status
make: *** [libns.dll] Error 1

This error is caused by declaring but not implementing one or more virtual function.

How to Fixed It?
Provide implementation to all virtual functions

The above is all you need to know to fix it. But if you want to understand more, read on.

What is vtable?

From [this Wikipedia], vtable is known by several names, including a virtual method table, virtual function table, and dispatch table. It is a mechanism to implement run-time method binding (a.k.a. dynamic dispatch). A lot of buzz words, eh? Well, let's boil them down to plain English, shall we?


Polymorphism is the ability of C++ to invoke the same function with different implementation under different context. Difficult to understand, right? So let's look at an example:

Example: Classifiers

Consider two main packet classifiers [Read more about classifiers here]:
  • Address classifiers: Select and send packet to the next NsObject based on the address.
  • Port classifiers: Select and send packet to the next NsObject based on the transport layer port.
The job description of both the classifiers is the same: To classifier and forward packets. The difference is how they classify the packets.

Polymorphism for Classifiers

Polymorphism defines a function classify(p) in class Classifier, and let the derived class defined their own way to classify packets. Usually, programmers would work with Classifier in their program. At run-time, the users chooses the classifier types (i.e., either address or port) based on their need, and instantiate objects accordingly. At the instantiation, objects morph (transform) itself from Classifier to either address classifier or port classifier.

So Where is Vtable?

Under the polymorphism concept, we need a mechanism to tell the program which implementation function classify(p) should use: Inspecting the address or inspecting the transport layer port. In C++, such the mechanism is vtable. Vtable stores the address which contains function implementation of each object. When a function is invoked, C++ identifies the object, and fetches the relevant implementation by looking at vtable.

About the Error

It should now be clear that if you do not provide implementation for virtual functions, C++ cannot construct vtable. Therefore, it shows the above error message on the screen.

A Common Error

Destructor is declared as virtual in class TclObject, which is the base class for almost every class in NS2. In your new class, you have few choices
  • Do not declare the destructor. In this case, the destructor of class TclObject will be used. 
  • If you declare the destructor, you MUST provide the implementation, even if it is an empty implementation (i.e., {}). Otherwise, you will see the above error message.
T. Issaraiyakul and E. Hossain, “Introduction to Network Simulator NS2”, Springer 2009.
You may also find lecture notes and other resource at the following website: http://www.ece.ubc.ca/~teerawat/NS2.htm

No comments: