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 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*
.