Binding type for a non-overriden virtual function

305 views Asked by At

Consider the case where a virtual function in base class is not overriden in the derived class. Then using a base class pointer to a derived class objectthe virtual function is invoked.

I understand that the function invocation will be resolved to the function in the base class during compile-time.

Question

Since the function is not overriden in the derived class, will the function call be bound to the function implementation during compile-time or will it still delay the binding until run-time?

2

There are 2 answers

6
Alok Save On BEST ANSWER

Most likely it will be resolved at compile time.
Most of the modern day compilers are smart enough to resolve dynamic dispatch at compilation time if there is enough credible information for them to decide so.
In this case since no overriding function is provided in the Derived class a smart compiler should be able to resolve the function call at compilation time statically.

2
6502 On

To be able to guess the implementation at compile time the compiler must know the type of the pointed to object... for example

MyBaseClass *p = new MyDerivedClass;
p->foo();

In the above a compiler should be smart enough to guess the type of the pointed-to object and the dispatching (assuming the compiler is using the VMT solution for late binding) should require no VMT lookup even if the method is virtual.

However for example in the following

void doit(MyBaseClass *p)
{
    p->foo();
    ...
}

the code for doit cannot know the type of the object pointed to and therefore the call will require a VMT lookup. Note that the C++ language has been designed so that compilers can work one compilation unit at a time, therefore there is no way the compiler can know that there is for example only one derived type in your program (the source code of another module could define a different derived class, even in a local unnamed namespace, where the function is overridden).

Of course the function doit could end up being inlined by the compiler and so a specific call site invoking doit could indeed require no lookup if the type can be inferred. But if the doit function is publically visible (e.g. it's not in the unnamed namespace or a static free function) then the machine code generated for it will include a VMT lookup when called from other complation units.

Note that in all this discussion about when a lookup is needed or not is totally irrelevant if the virtual function has been overridden or not. The reason is that if a virtual function has not been overridden and the dispatching is implemented with VMTs then simply the derived class VMT will have in that slot the address of the base implementation.

In other words what happens is that p->foo() is compiled as either

 p->__VMT__[__FOO_VMT_SLOT_NUMBER__](p);  // Dynamic dispatch

or

 __DERIVED_FOO_IMPLEMENTATION__(p); // Type known at compile time

where __DERIVED_FOO_IMPLEMENTATION__ is the function pointer stored in the VMT and it may be equal to the address of the base implementation or not depending on if the function has been overridden in the derived class.