c++ 中的 final 关键字是否允许额外的编译器优化

Does final keyword in c++ allow for additional compiler optimizations?

本文关键字:许额外 编译器 优化 是否 中的 final 关键字 c++      更新时间:2023-10-16

我在考虑虚拟通话及其工作原理。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型是声明为 final 的类(如在 c# 中密封),这是否允许编译器执行相同的操作?

这在当前的编译器中做了很多,还是只是理论上的/太小而不必担心?

是的,如果虚函数或类被声明为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(); }

-O1或更高处的 Clang 生成此程序集:

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 调用,而 f2f3 中的调用是非虚拟化的。

我在考虑虚拟通话及其工作原理。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型是声明为 final 的类(如在 c# 中密封),这是否允许编译器执行相同的操作?

是的,在gcc对最终成员的调用和通过最终类的调用将被去虚拟化,这是执行此操作的代码。