Reputation: 21538
#include <iostream>
using namespace std;
class C
{
public:
virtual void a();
};
class D : public C
{
public:
void a() { cout<<"D::a\n"; }
void b() { cout<<"D::b\n"; }
};
int main()
{
D a;
a.b();
return 0;
}
I am getting a link error about undefined reference to 'vtable for C'
. What does this mean and why is it?
I know the problem is obviously that the base class has a non-pure virtual function that is never defined, but why does this bother the linker if I am never calling it? Why is it different then any other function that I declare and don't define, that if I never call it I am fine?
I am interested in the nitty-gritty details.
Upvotes: 2
Views: 1852
Reputation: 320679
The need for actual function definition can arise in several circumstances. You already named one of such circumstances: the function has to be defined if you call it. However, this is not all. Consider this piece of code
void foo();
int main() {
void (*p)() = &foo;
}
This code never calls foo
. However, if you try to compile it, a typical compiler will complain about missing definition of foo
at linking stage. So, taking the address of a function (even if you never call it) happens to be one of the situations when the function has to be defined.
And this is where the matter of virtual functions come in. Virtual functions are typically implemented through a virtual table: a table that contains pointers to the definitions of the virtual functions. This table is formed and initialized by the compiler in advance, unconditionally, regardless of whether you actually call the functions or not. The compiler will essentially implicitly take the address of each non-pure virtual function in your program and place it into the corresponding table. For this reason, each non-pure virtual function will require a definition even if you never call it.
The exact virtual mechanism is an implementation detail, so you might end up with different specific errors is your situation (like a missing function definition or missing virtual table itself), but the fundamental reason for these error is what I described above.
Upvotes: 0
Reputation: 129504
If you want C
to be a pure virtual base-class, you need to tell the compiler "there will be no implementation of a()
", you do this by usring ... a() = 0;
to the declaration of the class. The compiler is trying to fing a base-class vtable, but there isn't one!
Upvotes: 0
Reputation: 994231
Most implementations of C++ compilers generate a vtable for each class, which is a table of function pointers for the virtual functions. Like any other data item, there can only be one definition of the vtable. Some C++ compilers generate this vtable when compiling the implementation of the first declared virtual function within a type (this guarantees that there is only one definition of the vtable). If you fail to provide an implementation for the first virtual function, your compiler does not generate the vtable and the linker complains about the missing vtable with a link error.
As you can see, the precise details of this depends on the implementation of your chosen compiler and linker. Not all toolchains are the same.
Upvotes: 9
Reputation: 121809
Q: I know the problem is obviously that the base class has a non-pure virtual function that is never defined
A: That's the answer to your question :)
Q: Why is it different then any other function that I declare and don't define, that if I never call it I am fine?
A: Because it's not just a "function". It's a virtual class method.
SUGGESTION:
Declare three different classes:
1) a simple method
2) a virtual method (as your "C" above)
3) an abstract virtual method ( = 0)
Generate assembly output (e.g. "-S" for GCC)
Compare the three cases. Carefully note if a *constructor" is created :)
Upvotes: 4