当派生类没有覆盖它时,编译器是否足够聪明来优化对 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)
这取决于。我刚刚在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 开发人员发表了一系列很好的博客文章,描述了去虚拟化优化技术。
| 归档时间: |
|
| 查看次数: |
109 次 |
| 最近记录: |