The Microsoft compiler allows you to add the “novtable” extension to the “__declspec” attribute when declaring a class.
The stated goal is to significantly reduce the size of the generated code. On experiments with our components, the reduction was from 0.6 to 1.2 percent of the size of the DLL.
Applicability: classes not intended to create instances directly from them.
')
For example: pure interface classes.
In code, it looks like this:
struct __declspec(novtable) IDrawable { virtual void Draw() const = 0; };
Note: The struct keyword was used to declare an interface class to eliminate the example of irrelevant details; whereas in the case of using a class, we would have to use public to indicate the “publicity” of the methods. For the same reason, I will not add a virtual destructor to the interface class in this article.The name “novtable” promises that there will be no virtual table ... But how does the mechanism for calling virtual functions work in the following code:
Recall what is added when declaring a virtual function in a class:
- Definition of the table of virtual functions. One instance of this table is used for all instances of the class.
- A pointer to a virtual function table is added to the class data members.
- The code for initializing this pointer in the class constructor.
Thus, in our example, there will be a declaration of two tables of virtual functions: for IDrawable and for Rectangle. When creating a Rectangle object, the IDrawable constructor is first executed, which initializes a pointer to its virtual function table. Schematically it looks like this:

Since the draw function in IDrawable is declared pure-virtual (indicated by "= 0" instead of the function body), the address of the purecall function generated by the compiler is written in the virtual functions table.
Then the Rectangle constructor is executed, which initializes the same pointer, but to its virtual function table:

What does “novtable” do, and why does Microsoft promise to reduce the size of the code?
It is the unnecessary definition of the table of virtual functions IDrawable and the initialization of a pointer to it in the IDrawable constructor that are excluded from the resulting code when adding “novtable”.
In this case, when constructing an IDrawable, the pointer to the virtual function table will contain an unpredictable value. But this should not worry us, since the creation of an implementation with reference to virtual functions before the complete construction of the object, as a rule, is an error. If, for example, in the constructor of the base class to call a non-virtual function of this class, which in turn calls a virtual function, then without notable the purecall function will be called, and with novtable there will be unpredictable behavior; none of the options can be acceptable.
Note that there is not only a reduction in size, but also some acceleration of the program.
RTTI
As you know, std :: dynamic_cast allows you to cast pointers and references from one class instance to a pointer and a link to another if these classes are linked by a hierarchy and are polymorphic (contain a table of virtual functions). In turn, the typeid operator allows you to get information about an object at runtime using a pointer (reference) to the object passed to it. These capabilities are provided by the RTTI mechanism, which uses type information located with reference to the vtable class. Details of the structure and location depend on the compiler. In the case of the Microsoft compiler, it looks like this:

Therefore, if the compiler is ordered to include RTTI when building, then novtable also excludes the creation of a type_info definition for the IDrawable and the service data required for it.
Note that if you somehow have the knowledge that the pointer (reference) to the base class points to the implementation of the derivative, then std :: static_cast is more efficient and does not require RTTI.
Microsoft specific
In addition to MSVC, this feature with the same syntax is present in Clang when compiled under Windows.
findings
- __declspec (novtable) - does not affect the amount of memory occupied by instances of the class.
- Reducing the size and some acceleration of the program is provided by eliminating the definition of unused virtual function tables, RTTI service data and eliminating the initialization code of the pointer to the virtual functions table in the interface class constructors.