c++ 中的 final 关键字是否允许额外的编译器优化?
Does final keyword in c++ allow for additional compiler optimizations?
我在考虑虚拟电话及其工作方式。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型是 class 声明为 final(如在 c# 中密封),这是否允许编译器做同样的事情?
这在当前的编译器中做了很多还是只是 theoretical/too 需要担心的小事?
是的,如果声明了虚函数或 class 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
中的调用是去虚拟化的。
I was thinking about virtual calls and how they work. I understand that virtual calls can be inlined and hardcoded at compile time for value types. If the pointer type is of a class declared as final (like sealed in c#) could this allow the compiler to do the same thing?
是的,在 gcc
对 final 成员的调用中以及通过 final 类 将被去虚拟化,here's the code 就是这样。
我在考虑虚拟电话及其工作方式。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型是 class 声明为 final(如在 c# 中密封),这是否允许编译器做同样的事情?
这在当前的编译器中做了很多还是只是 theoretical/too 需要担心的小事?
是的,如果声明了虚函数或 class 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
中的调用是去虚拟化的。
I was thinking about virtual calls and how they work. I understand that virtual calls can be inlined and hardcoded at compile time for value types. If the pointer type is of a class declared as final (like sealed in c#) could this allow the compiler to do the same thing?
是的,在 gcc
对 final 成员的调用中以及通过 final 类 将被去虚拟化,here's the code 就是这样。