c++ 中的 final 关键字是否允许额外的编译器优化
Does final keyword in c++ allow for additional compiler optimizations?
我在考虑虚拟通话及其工作原理。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型是声明为 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 调用,而 f2
和 f3
中的调用是非虚拟化的。
我在考虑虚拟通话及其工作原理。我知道虚拟调用可以在编译时对值类型进行内联和硬编码。如果指针类型是声明为 final 的类(如在 c# 中密封),这是否允许编译器执行相同的操作?
是的,在gcc
对最终成员的调用和通过最终类的调用将被去虚拟化,这是执行此操作的代码。
相关文章:
- C/C++编译器通常会删除重复的库吗
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- Win32编译器选项和内存分配
- MSVC多行宏编译器错误
- 静态数据成员的问题-修复链接错误会导致编译器错误
- 如何防止 c++ 在从浮点型转换为双精度型(不适用于 IO)时添加额外的小数?
- C++,我收到一个无法理解的编译器错误
- 在线编译器中的分段C++没有打印消息
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- C/C++预处理器是否可以检测一些编译器选项
- 添加额外的恒常性会导致编译器错误
- 链接QT5库会自动将额外的FPIC标志传递给NVCC编译器,并通过cmake Cause错误
- 常量右值引用是否允许对编译器进行额外优化?
- 当我们声明额外的模板参数而未在定义中使用时,为什么编译器会丢弃错误
- Android Cmake编译器正在生成带有额外前缀和符号后缀的.out文件
- c++ 中的 final 关键字是否允许额外的编译器优化
- 为什么当 typedef const 指针与额外的 const 一起使用时,编译器不会给出错误?
- 在linux上单开发额外的g++编译器选项
- 为什么额外的-I标志(包括目录)会中断编译?(使用英特尔编译器)
- 在c++11编译器中有一个额外的限定错误