Specifying Compiler Optimization for an ATL Project
By default, the ATL Control Wizard generates new classes with the ATL_NO_VTABLE macro, as follows:
class ATL_NO_VTABLE CProjName
{
...
};
ATL then defines _ATL_NO_VTABLE as follows:
#ifdef _ATL_DISABLE_NO_VTABLE
#define ATL_NO_VTABLE
#else
#define ATL_NO_VTABLE __declspec(novtable)
#endif
If you do not define _ATL_DISABLE_NO_VTABLE, the ATL_NO_VTABLE macro expands to declspec(novtable)
. Using declspec(novtable)
in a class declaration prevents the vtable pointer from being initialized in the class constructor and destructor. When you build your project, the linker eliminates the vtable and all functions to which the vtable points.
You must use ATL_NO_VTABLE, and consequently declspec(novtable)
, with only base classes that are not directly creatable. You must not use declspec(novtable)
with the most-derived class in your project, because this class (usually CComObject, CComAggObject, or CComPolyObject) initializes the vtable pointer for your project.
You must not call virtual functions from the constructor of any object that uses declspec(novtable)
. You should move those calls to the FinalConstruct method.
If you are unsure whether you should use the declspec(novtable)
modifier, you can remove the ATL_NO_VTABLE macro from any class definition, or you can globally disable it by specifying
#define _ATL_DISABLE_NO_VTABLE
in pch.h (stdafx.h in Visual Studio 2017 and earlier), before all other ATL header files are included.
See also
ATL Project Wizard
C++ project types in Visual Studio
Programming with ATL and C Run-Time Code
Fundamentals of ATL COM Objects
novtable
Default ATL Project Configurations