Please do not answer the question "how do I solve this error message?"
In the error message provided by gold:
/usr/bin/ld.gold: the vtable symbol may be undefined
because the class is missing its key function
What is a key function
? I find reference to it in the GCC manual page for Function Attributes under the section dllimport
. The relevant text reads:
On the SH Symbian OS target the dllimport attribute also has another affect (sic)—it can cause the vtable and run-time type information for a class to be exported. This happens when the class has a dllimport'ed constructor or a non-inline, non-pure virtual function and, for either of those two conditions, the class also has an inline constructor or destructor and has a key function that is defined in the current translation unit.
From this I take away that there is some function distinct from constructors or destructors, required under some conditions, when using the dllimport
attribute, on Symbian OS. Interesting, but I'm compiling for Linux on Linux, and grep -r dllimport
reveals nothing. So this paragraph does not apply.
(FWIW the problem derives (in this instance) from an undefined destructor but both the documentation and the output of the linker go to great pains to distinguish a "key function" from a destructor. For other kinds of missing symbols, the linker spells the name of the missing symbol.)
So, what is a key function
really?
key function is defined as the first non-inline, virtual function declared in the class. The official gcc wiki about it is here.
(moving/expanding from the comment)
As @navylover explained, the key function is the first non-inline, virtual function defined in the class; it's important because it is used by the compiler as a conventional marker to decide in what TU the vtable must be emitted (as it must be emitted just once) - whichever TU contains the definition of the key function, the corresponding object module will contain the vtable as well.
It follows that, if no TU defines the key function (e.g. because you forgot to define it), the vtable will never get emitted, hence the error.
gold there is trying to hint you in the right direction: if the vtable is missing, probably is because the key function is missing as well (again, either because you didn't define or forgot to link its module), although it may not be listed explicitly as an undefined reference (which could put you on the right track) because in the rest of the code nobody invokes it directly1, as in this example:
struct Test {
virtual void foo();
virtual int bar() {
return 0;
}
};
int main() {
Test t;
t.bar();
return 0;
}
[matteo@teolapkubuntu /tmp]$ g++ -fuse-ld=gold keyf.cpp
/tmp/ccduMsT3.o:keyf.cpp:function main: error: undefined reference to 'vtable for Test'
/usr/bin/ld.gold: the vtable symbol may be undefined because the class is missing its key function
Compare this with regular GNU ld, which just says
[matteo@teolapkubuntu /tmp]$ g++ keyf.cpp
/tmp/ccUr3Xyi.o: In function `main':
keyf.cpp:(.text+0x1a): undefined reference to `vtable for Test'
collect2: error: ld returned 1 exit status
Ok, so what? It's not like I have to explicitly define vtables, so it's definitely not obvious where should I start to look to go fixing this kind of error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With