我在考虑虚拟电话及其工作方式。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型属于声明为 final 的类(如 c# 中的 sealed),这是否允许编译器执行相同的操作?
这在当前的编译器中做了很多,还是只是理论上的/太小而无需担心?
最佳答案
是的,如果虚函数或类被声明为 final
,调用可以被去虚化。例如,给定
struct B {
virtual void f() = 0;
};
struct D1 : B {
virtual void f();
};
struct D2 : B {
virtual void f() final;
};
struct D3 final : D1 {};
void f1(D1 * d) { d->f(); }
void f2(D2 * d) { d->f(); }
void f3(D3 * d) { d->f(); }
Clang 在 -O1
或更高级别 generates这个大会:
f1(D1*): # @f1(D1*)
movq (%rdi), %rax
jmpq *(%rax) # TAILCALL
f2(D2*): # @f2(D2*)
jmp D2::f() # TAILCALL
f3(D3*): # @f3(D3*)
jmp D1::f() # TAILCALL
请注意,f1
调用是通过 vtable 进行的,而 f2
和 f3
中的调用是去虚拟化的。
关于c++ - c++ 中的 final 关键字是否允许额外的编译器优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28957312/