c ++中的final关键字是否允许其他编译器优化?

时间:2015-03-10 06:20:46

标签: c++ inheritance virtual compiler-optimization final

我在考虑虚拟通话以及它们的工作原理。据我所知,虚拟调用可以在编译时内联并硬编码为值类型。如果指针类型是一个声明为final的类(比如用c#密封),这可以让编译器做同样的事情吗?

这在目前的编译器中是否完成了很多,还是只是理论上的/太小而无法担心?

2 个答案:

答案 0 :(得分:4)

是的,如果声明虚拟函数或类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或更高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进行了调用,而f2f3中的来电是非虚拟化的。

答案 1 :(得分:2)

  

我在考虑虚拟通话以及它们的工作原理。据我所知,虚拟调用可以在编译时内联并硬编码为值类型。如果指针类型是一个声明为final的类(比如用c#密封),这可以让编译器做同样的事情吗?

是的,在gcc调用最终成员并通过最终课程将被虚拟化,并here's the code执行此操作。