Vtable placement of completely pure-virtual class
Asked Answered
R

3

5

According to my (limited) knowledge of the C++ spec, the vtable of a class with virtual members is placed at the definition of the first non-pure non-inline virtual method. How do compilers handle classes which inherit from a class with ALL pure virtual methods (interfaces, for example)? Where is the vtable placed in this case?

Rivera answered 6/1, 2011 at 18:5 Comment(2)
The C++ spec itself says nothing of vtables.Godparent
A heavy implementation detail. MSVC++ has __declspec(novtable) to suppress such a vtable. And the non-standard __interface keyword to do the same.Logrolling
P
6

The vtable stores the addresses of the implemented virtual methods. If all methods of a class are pure-virtual and none are implemented, then no vtable needs to be generated.

You could not use such a class for much without some classes which derive from it and implement the methods. Each class with implemented virtual methods has its own single vtable containing addresses for all virtual methods: it does not in any way reference the vtables of base classes; the addresses are duplicated. So if you have a class which inherits from another class, that class will use just its own vtable. It doesn't care about the vtable of the base class; this vtable doesn't even need to exist.

The C++ specification itself says nothing about vtables; they are simply a compiler behaviour which has become common.

EDIT from 2020: I wrote this almost a decade ago. I suspect I wrote it from memory and personal experience. Two comments below indicate that compilers do make vtables for base classes (to throw errors), although if so I don't know how you would construct an object for them, and that some compilers do reuse vtables of base classes. Nobody seems to have added anything since 2011, and I have cognitive decline now and it's hard to really think much anymore, so do some research of your own if some detail here is crucial.

Pulsatory answered 6/1, 2011 at 18:12 Comment(7)
Interesting. I would have thought that having duplicate tables would have violated some sort one definition rule.Rivera
None of the tables are duplicate. A new table is only generated if a virtual method is implemented by that class; this makes a unique vtable containing a pointer to that implementation. The table will contain duplicate addresses for any unchanged virtual methods.Pulsatory
<quote>If all methods of a class are pure-virtual, none are implemented</quote> This is just not true. In C++, pure virtual does not mean no implementation.Niggard
Ben, you are correct. I have edited my answer and voted up yours.Pulsatory
Actually compiler will generate entries for pure virtual functions with error stubs even when they have no user-defined implementation. This is done to catch and report errors when pure virtual function is called.Unglue
<quote>Each class with implemented virtual methods has its own single vtable containing addresses for all virtual methods: it does not in any way reference the vtables of base classes</quote> -- This is not necessary true. Some old Borland compilers implemented exactly pointer to base vmt scheme to save memory. Nobody seems to be concerned with that anymore.Unglue
Does GCC have the behaviour you describe? Where does it place its vtable for pure virtual base classes? It would be great to have a proper answer to the question.Pulsatory
N
3

The C++ standard doesn't specify anything about vtable placement, or even the existence of a v-table. It just specifies behavior, and a v-table happens to be the most straightforward implementation, hence widely used.

Practically speaking, the one reason for a v-table to exist for an abstract class is for use during construction and destruction, when the dynamic type of the object is the abstract class.

In a class with only pure virtual functions, there clearly can be no constructors (since constructors cannot be virtual). However, destructors certainly CAN be virtual.

Your class could still have a pure virtual destructor with an implementation and then the v-table (or equivalent implementation details) is required.

But implementations of pure virtual functions are rare, and wouldn't be done when defining an interface.

Niggard answered 6/1, 2011 at 18:31 Comment(0)
K
2

You don't need a vtable until you have an instance.

Kreis answered 6/1, 2011 at 18:6 Comment(2)
What instance? Compiler has no idea when compiling a single TU, whether pure virtual functions will have implementation defined in another TU. Compiler implementer can decide how to deal with it, and it can be a reasonable solution to create vtable and set pointers to error function to report illegal calls to undefined pure virtual functions.Unglue
It's been some time since I wrote this (notified by edit), but I suppose my point was: either it's abstract (has pure virtual methods), hence can't be instanciated and doesn't need a vtable, or it's not, hence has all inherited pure virtual methods overridden. OP's case is the all-pure abstract one. Compiler is supposed to know, when compiling any TU, whether methods are pure or not, as it's contained in the class declaration.Kreis

© 2022 - 2024 — McMap. All rights reserved.