Search code examples
c++objectmethodsoverridingvirtual-functions

Should virtual dispatch happen when a virtual method is called within a virtual method using object?


struct B
{
  virtual void bar () {}
  virtual void foo () { bar(); }
};

struct D : B
{
  virtual void bar () {}
  virtual void foo () {}
};

Now we call foo() using an object of B as,

B obj;
obj.foo();  // calls B::bar()

Question: Should bar() will be resolved through virtual dispatch or it will be resolved using the static type of the object (i.e. B).


Solution

  • Entirely up to the implementation. Nominally it's a virtual call, but you're not entitled to assume that the emitted code will actually perform an indirection through a vtable or similar.

    If foo() is called on some arbitrary B*, then of course the code emitted for foo() needs to make a virtual call to bar(), since the referand might belong to a derived class.

    This isn't an arbitrary B*, this is an object of dynamic type B. The result of a virtual or non-virtual call is exactly the same, so the compiler can do what it likes ("as-if" rule), and a conforming program can't tell the difference.

    Specifically in this case, if the call to foo is inlined, then I'd have thought that the optimizer has every chance of de-virtualizing the call to bar inside it, since it knows exactly what's in the vtable (or equivalent) of obj. If the call isn't inlined, then it's going to use the "vanilla" code of foo(), which of course will need to do some kind of indirection since it's the same code used when the call is made on an arbitrary B*.