In this answer to "In C++ why and how are virtual functions slower?", the author mentions below point:

"Get the right function address from the vtable into a register (the index where the correct function address is stored is decided at compile-time)."

As a follow up of this comment, i have some questions:

  1. What is the order of function pointers stored inside the vtable? Is it compiler dependent or all compilers have to implement it the same way?

  2. If compilers are free to implement it in their own way, then how does binary standard's like COM works. COM relies on the assumption that vtables are implemented in a uniform way by compilers, in order to pass IUnknown pointers to a component compiled by a different compiler. Isn't it?

2 Answers 2


While it is implementation dependent, it is also fairly predictable.  Especially historically speaking, the compilers layout members in declaration order.  For fields (instance data) that means each field get assigned the next offset in the object (after alignment is rounded up as required), and, each virtual method that is introduced, is assigned next vtable slot.  (Overrides share the same vtable slot as the virtual method that they override in the base class.)

Multiple inheritance complicates field & vtable layouts, introducing a notion of sections that group the field and vtable entries, and, the generated code has to switch between sections as their usage demands.

Because among other things, C is the default standard for foreign function calling, many tools and programs rely on C to layout structs in the predictable order they have always done.

C++ compilers are allowed some latitude for certain constructs these days, but as you have described, to be used with COM (which is of course a Microsoft standard, not a C++ language standard), they have also need to be predictable.

See also:



  • Of course the order of fields of C structs is constrained much more by the specification. Anything with virtual members is not “standard layout object” and therefore is not bound by the rules—but in practice the compilers still follow most of them as there is no reason to create another, separate layout algorithm.
    – Jan Hudec
    Commented May 8, 2019 at 20:39
  • "Overrides share the same vtable slot as the virtual method that they override in the base class" When the declaration matches the one in the base class; it's a lot more complicated when return types differ. (You need to account for MI and virtual inheritance.)
    – curiousguy
    Commented Jun 4, 2019 at 18:55

It's all up to the implementation. There is no requirement that virtual functions be implemented by a per-class vtable, a per-object vtable, or any other mechanism.

An implementation can choose to be compatible with some particular object layout and calling convention, (e.g. COM), but it isn't required to.

  • 12
    … and strictly speaking, it need not use a vtable at all. Though AFAIK, that's purely academic at best. Commented May 7, 2019 at 11:03
  • 3
    @Deduplicator: Well, the LLVM codebase is relatively famous for doing its own virtual-dispatch based on storing a hierarchy-specific enum field in the base class and then switching on it. It just requires a sealed hierarchy... Commented May 7, 2019 at 14:28
  • 1
    @MatthieuM. Yes, it is. But that's user-code. Commented May 7, 2019 at 21:04
  • 1
    @Deduplicator: Sure. I see it as a proof of concept that this is feasible; it's just that the requirement of a sealed hierarchy essentially requires Whole Program Analysis, which itself requires compiling the whole program in one shot. Commented May 8, 2019 at 10:46
  • 1
    The implementation is, however, required to define the calling convention in a fully deterministic way and stick to it, so that separately compiled objects can be linked together.
    – Jan Hudec
    Commented May 8, 2019 at 20:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.