Consider the following:
In X.h:
class X
{
X();
virtual ~X();
};
X.cpp:
#inclu
You have the code for the constructor.
So it builds the constructor into the object file. The constructor needs the address of the destructor to put into the virtual table because it can not find it the constructor can not be built.
The compiler decides it does not need to build the constructor (as it will be inlined).
As such it does not plant any code and therefore does not need the address of the destructor.
If you instanciate an object of type X it will again complain.
You don't need the address of the destructor to build the constructor.
So it does not complain.
It will complain if you instantiate an object of type X.