空基虚拟方法是否被优化?

Des*_*ess 3 c++

当派生类没有覆盖它时,编译器是否足够聪明来优化对 Foo() 的调用?

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;
}
Run Code Online (Sandbox Code Playgroud)

Jen*_*ens 5

这取决于。我刚刚在Godbolt 编译器资源管理器中粘贴了您的示例。我不得不 delcare 一个函数void Bar(int)以使其可编译,并且我添加了缺少的deletes。Clang 用“-O2”很好地优化了它

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
Run Code Online (Sandbox Code Playgroud)

而具有相同优化级别的 gcc 生成调用。稍微修改您的示例以使用本地堆栈对象而不是堆上的两个新对象,以使 gcc 能够消除虚拟函数调用。

GCC 开发人员发表了一系列很好的博客文章,描述了去虚拟化优化技术。