В каком TU генерируется виртуальная таблица, если функции inline?
В каком/каких TU генерируется vtable для класса, содержащего только inline виртуальные функции?
Например, есть хедер S.h:
struct S {
virtual foo() {}
};
И несколько компилируемых файлов A.cpp, B.cpp, которые включают этот хедер. В каком TU будет сгенерирован vtable?
Ответы (2 шт):
vtable генерируется в конечном бинаре, при условии, что класс там использован таким образом, что в ней появляется необходимость, т.е. когда реально присутствуют неоптимизированные вызовы его виртуальных функций. Современные компиляторы производят кодогенерацию оптимизированного кода не при создании TU, а потом, когда происходит линковка этих TU в бинарь.
https://gcc.gnu.org/wiki/VerboseDiagnostics#missing_vtable
Every polymorphic class requires a virtual table or vtable describing the type and its virtual functions. Whenever possible the vtable will only be generated and output in a single object file rather than generating the vtable in every object file which refers to the class (which might be hundreds of objects that include a header but don't actually use the class.) The cross-platform C++ ABI states that the vtable will be output in the object file that contains the definition of the key function, which is defined as the first non-inline, non-pure, virtual function declared in the class. If you do not provide a definition for the key function (or fail to link to the file providing the definition) then the linker will not be able to find the class' vtable.
https://lld.llvm.org/missingkeyfunction.html#missing-key-function
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.