It is said that virtual functions cannot be inlined. Is it always true that if a function is declared virtual, it cannot be inlined anywhere in the code, or is it applicable only under certain situations? (eg., calling method from a base pointer vs. calling method on a reference, etc.)
No, virtual functions can indeed be inlined. Virtual dispatch is only used when calling a virtual method polymorphically (i.e., on a pointer or reference to an object). However, when a virtual method is called on an object value, virtual dispatch is not used and the compiler is free to inline as it sees fit.
Given:
struct T {
virtual void foo() { /* something */ }
};
Using polymorphism (If you're calling foo()
through a pointer-to-T
or a reference-to-T
)
T* ptr = get_ptr_somehow();
ptr->foo();
If a compiler knows that T
is the only node in its inheritance tree, it could forego the virtual calls and potentially inline the function. However, this is an incredibly unlikely scenario and I doubt whether it could even feasibly be detected. In all other cases, inlining is not practical due to the run-time dispatch.
Static dispatch (If you're calling foo()
on a bog-standard object)
T obj;
obj.foo();
In this case, the compiler knows that the dynamic type of obj
is T
, that it does not require virtual dispatch, and therefore may inline the function code if it wants to.
T* ptr = get_ptr_somehow();
ptr->T::foo();
In this case, the compiler doesn't know the dynamic type of obj
, but it knows which function it's going to call, knows that it does not require virtual dispatch, and therefore may inline the function code if it wants to.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With