2

The following piece of code give me the error

undefined reference to `vtable for Derived'

Code :

#include <iostream>
class base{
    public:
    base(){}
    virtual ~base(){}
    virtual void test()
    {
    }
};
class Derived:public base{
    public:
    Derived(){}
    ~Derived(){}  
    void test();
};
int main() {
    base* b = new Derived ();
    delete b;
}

which i understand is because the virtual fucntion test is declared but not defined in class Derived.

But when i compile with g++ -c file.cpp which as per this Compile or assemble the source files, but do not link. It does not give me any errors and compiles fine. Hence the above error is generated at linking time and not compile time. From what i learned wasn't the vtable created at compile time. Then why do i not get the error at compile time itself?

Hummingbird
  • 647
  • 8
  • 27
  • The error is from the linker, as a moment's inspection would have shown you. – user207421 Nov 19 '16 at 09:16
  • @EJP yes i do realize that and has mentoined the very same in question itself. but what i dont understand is that shouldn't i be gettng it at compile time itself rather than linking. – Hummingbird Nov 19 '16 at 09:20
  • 2
    the description "at compile-time" includes link time, but not runtime – M.M Nov 19 '16 at 09:35
  • 1
    when compiling `file.cpp` there is no error because the vtable might be found in a different unit, it is only when you get to linking that the linker sees it is not in any unit – M.M Nov 19 '16 at 09:37

4 Answers4

2

What I get with g++ foo.cpp -v

/tmp/ccBc4VPu.o: In function `Derived::Derived()':
foo.cpp:(.text._ZN7DerivedC2Ev[_ZN7DerivedC5Ev]+0x1f): undefined reference to `vtable for Derived'
collect2: error: ld returned 1 exit status

That's a linker error, not a compiler error per se.

The root cause of the error is that test is declared in Derived, but not actually implemented. The linker is giving a confusing error message. It should be declaring an error for the missing Derived::test method

selbie
  • 100,020
  • 15
  • 103
  • 173
  • thats the exact question why this is linker error? from what i learned vtables were created at compile time? so it would great to learn why i do not get the error also at compile time itself rather at linking time. – Hummingbird Nov 19 '16 at 09:18
2

Compiler doesn't require to have all methods available. It's enough for him to have their declaration.

This method could be implemented in different compilation unit (cpp/cxx file) so for compiler it's not even possible to check if this method is available somewhere else. Compiler process one cpp file at time.

It's linker job to match methods and calls together.

woockashek
  • 1,588
  • 10
  • 25
2

However you formed the view that a vtable must be created at compile time, you are mistaken.

Separate compilation is a core concept in the standard. It is the reason that a compilation unit (aka source file) can compile, given any declaration of a function it needs - even if it doesn't have visibility of the definition.

In the typical "compile then link" build chain, this allows a compilation unit (source file) to compile, given any declaration of a function (member function or not) that might be defined in another compilation unit.

The absence of the definition of a function then needs to be detected by the linker.

Practically, this means that the compiler may emit information about the vtable, but it will be the linker that (ahem) links the specification of the vtable to the actual member functions.

Peter
  • 35,646
  • 4
  • 32
  • 74
  • Thanks .. now i think i do understand it... and for vtable part i took ref from [here](http://stackoverflow.com/questions/3849498/when-is-vtable-in-c-created) – Hummingbird Nov 19 '16 at 09:42
  • That link simply says that creation of the vtable is handled by the implementation. It doesn't say it happens solely during compilation. In a "compile then link" toolchain, the linker is a component of the implementation. – Peter Nov 19 '16 at 09:43
  • I Agree with you and undertand your point.. though the link does say quoting **vtables are structures created at compile time** anyway which got me confused. – Hummingbird Nov 19 '16 at 09:45
  • 1
    Yeah, okay. There is a difference between specifying a vtable (e.g. its layout) and populating it. The answer in that link is using the word "created" when it probably should use the wording "specify the layout". " – Peter Nov 19 '16 at 09:47
  • So just to understand better..the layout of vtables is specified at compile time but it is populated at linking time.. if i am getting it correct? .. hence the complete "compile then link chain" matters. right? – Hummingbird Nov 19 '16 at 09:49
  • The details vary between different toolchains but, generally speaking, that'll do. – Peter Nov 19 '16 at 10:04
1

GCC has an FAQ entry for this problem:

When building C++, the linker says my constructors, destructors or virtual tables are undefined, but I defined them

The solution is to ensure that all virtual methods that are not pure are defined. Note that a destructor must be defined even if it is declared pure-virtual [class.dtor]/7.

Community
  • 1
  • 1
Nikita
  • 6,270
  • 2
  • 24
  • 37
  • Thanks, i understand this but what i m not able to understand is that "if vtable is created at compile time, then why i do not get the error also compile time only but rather get at linking time.". if thats not too much to ask. – Hummingbird Nov 19 '16 at 09:22
  • 1
    @DevanshMohanKaushik vtable is allocated by the compiler and initialized by the linker. Looks like Peters described this in details. – Nikita Nov 19 '16 at 10:17
  • yeah thats what i was confused about.. Thanks anyways – Hummingbird Nov 19 '16 at 10:20