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).
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 arbitraryB*, then of course the code emitted forfoo()needs to make a virtual call tobar(), since the referand might belong to a derived class.This isn’t an arbitrary
B*, this is an object of dynamic typeB. 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
foois inlined, then I’d have thought that the optimizer has every chance of de-virtualizing the call tobarinside it, since it knows exactly what’s in the vtable (or equivalent) ofobj. If the call isn’t inlined, then it’s going to use the “vanilla” code offoo(), 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 arbitraryB*.