Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are empty base virtual methods optimized out?

Tags:

c++

Are compilers smart enough to optimize the call to Foo() when derived class does not override it?

struct Base {
    virtual void Foo(int x) {}
};

struct DerivedA : Base {};

struct DerivedB : Base {
    void Foo(int x) override { Bar(x); }
};

void Call(Base* b) {
    b->Foo(42); // Is this optimized out for DerivedA?
}

int main() {
    Base* a = new DerivedA();
    Base* b = new DerivedB();
    Call(a);
    Call(b);

    return 0;
}
like image 215
Dess Avatar asked Mar 20 '26 13:03

Dess


2 Answers

It depends. I just pasted your example in Godbolt compiler explorer. I had to delcare a function void Bar(int) to make it compileable, and I added missing deletes. Clang optimizes it with "-O2" pretty well to

Call(Base*):                          # @Call(Base*)
        mov     rax, qword ptr [rdi]
        mov     rax, qword ptr [rax]
        mov     esi, 42
        jmp     rax                             # TAILCALL
main:                                   # @main
        xor     eax, eax
        ret

while gcc with the same optimization level generates the call. Slightly modifying your example to use local stack objects instead of two objects newed on the heap to enables gcc to eliminate the virtual function call.

There is a nice series of blog posts from a GCC developer describing the devirtualization optimization technique.

like image 133
Jens Avatar answered Mar 23 '26 04:03

Jens


Optimization rely on as-if rule and "quality" of compiler, so it depends.

Are empty base virtual methods optimized out?

With enough visibility for compiler, calls can be devirtualized completely and then empty function can be removed.

Final executable might simply be

Bar(42);
like image 34
Jarod42 Avatar answered Mar 23 '26 02:03

Jarod42