Search code examples
c++compilationinlinevirtualfinal

C++ virtual function inlining when derived class is final?


I'm using C++ in an embedded environment where the runtime of virtual functions does matter. I have read about the rare cases when virtual functions can be inlined, for example: Are inline virtual functions really a non-sense? The accepted answer states that inlining is only possible when the exact class is known at runtime, for example when dealing with a local, global, or static object (not a pointer or reference to the base type). I understand the logic behind this, but I wonder if inlining would be also possible in the following case:

class Base {

    public:

        inline virtual void x() = 0;
}

class Derived final : Base {

    public:

        inline virtual void x(){
            cout << "inlined?";
        }
}

int main(){
    Base* a;
    Derived* b;

    b = new Derived();
    a = b;

    a->x(); //This can definitely not be inlined.
    b->x(); //Can this be inlined?
}

From my point of view the compiler should know the definitive type of a at compiletime, as it is a final class. Is it possible to inline the virtual function in this case? If not, then why? If yes, then does the gcc-compiler (respectively avr-gcc) does so?

Thanks!


Solution

  • The first step is called devirtualization; where a function call does not go through virtual dispatch.

    Compilers can and do devirtualize final methods and methods of final classes. That is almost the entire point of final.

    Once devirtualized, methods can be inlined.

    Some compilers can sometimes prove the static type of *a and even devirtualize that. This is less reliable. Godbolt's compiler explorer can be useful to understand what specific optimizations can happen and how it can fail.