| # Missing Key Function | |
| If your build failed with a linker error something like this: | |
| ``` | |
| foo.cc:28: error: undefined reference to 'vtable for C' | |
| the vtable symbol may be undefined because the class is missing its key function | |
| (see https://lld.llvm.org/missingkeyfunction) | |
| ``` | |
| it's likely that your class C has a key function (defined by the ABI as the first | |
| non-pure, non-inline, virtual function), but you haven't actually defined it. | |
| When a class has a key function, the compiler emits the vtable (and some other | |
| things as well) only in the translation unit that defines that key function. Thus, | |
| if you're missing the key function, you'll also be missing the vtable. If no other | |
| function calls your missing function, you won't see any undefined reference errors | |
| for it, but you will see undefined references to the vtable symbol. | |
| When a class has no non-pure, non-inline, virtual functions, there is no key | |
| function, and the compiler is forced to emit the vtable in every translation unit | |
| that references the class. In this case, it is emitted in a COMDAT section, | |
| which allows the linker to eliminate all duplicate copies. This is still | |
| wasteful in terms of object file size and link time, so it's always advisable to | |
| ensure there is at least one eligible function that can serve as the key function. | |
| Here are the most common mistakes that lead to this error: | |
| ## Failing to define a virtual destructor | |
| Say you have a base class declared in a header file: | |
| ``` | |
| class B { | |
| public: | |
| B(); | |
| virtual ~B(); | |
| ... | |
| }; | |
| ``` | |
| Here, `~B` is the first non-pure, non-inline, virtual function, so it is the key | |
| function. If you forget to define `B::~B` in your source file, the compiler will | |
| not emit the vtable for `B`, and you'll get an undefined reference to "vtable | |
| for B". | |
| This is just an example of the more general mistake of forgetting to define the | |
| key function, but it's quite common because virtual destructors are likely to be | |
| the first eligible key function and it's easy to forget to implement them. It's | |
| also more likely that you won't have any direct references to the destructor, so | |
| you won't see any undefined reference errors that point directly to the problem. | |
| The solution in this case is to implement the missing function. | |
| ## Forgetting to declare a virtual function in an abstract class as pure | |
| Say you have an abstract base class declared in a header file: | |
| ``` | |
| class A { | |
| public: | |
| A(); | |
| virtual ~A() {} | |
| virtual int foo() = 0; | |
| ... | |
| virtual int bar(); | |
| ... | |
| }; | |
| ``` | |
| This base class is intended to be abstract, but you forgot to mark one of the | |
| functions pure. Here, `A::bar`, being non-pure, is nominated as the key function, | |
| and as a result, the vtable for `A` is not emitted, because the compiler is | |
| waiting for a translation unit that defines `A::bar`. | |
| The solution in this case is to add the missing `= 0` to the declaration of | |
| `A::bar`. | |
| ## Key function is defined, but the linker doesn't see it | |
| It's also possible that you have defined the key function somewhere, but the | |
| object file containing the definition of that function isn't being linked into | |
| your application. | |
| The solution in this case is to check your dependencies to make sure that | |
| the object file or the library file containing the key function is given to | |
| the linker. | |