Is this a compiler error, an optimizer problem, or a dark corner of a standard surprise?
None of the above. This is not a mistake, it is not related to optimization, and this particular problem is beyond the scope of the standard, it covers the corresponding ABI (which is only the de facto standard.)
C::m is a key function , and you haven't defined it anywhere, which means the compiler does not allocate vtable.
There are good (if complex) reasons why the code compiles with these changes:
- Remove non-embedded implementation for C :: C () from .cpp implementation
For some complex reasons, described in 2.6 in the ABI document, vtables must be used during construction. Thus, the definition of the constructor creates a link to the vtable, which, according to the linker, is missing during the link. If you delete the constructor definition, then there is no reference to vtable.
- Add a trivial inline implementation for C () to a class in Header.h
A built-in function that is not called in this translation unit will not be selected in the object file, so the inclusion of the inline function means that the constructor is not in the object file, therefore the object file does not reference the vtable and the linker does not need to be searched at the time of the link.
If you change the program so that the built-in constructor is actually used (for example, by creating C in main ), you will again get the same linker error, because now the built-in constructor will be defined in Main.o and therefore vtable is needed.
class C { public: C() { }