c++ - 非 final方法去虚拟化

标签 c++ gcc g++ c++14

假设我有一个类设置如下:

class A {
  public:
    virtual void foo() { printf("default implementation\n"); }
};

class B : public A {
  public:
    void foo() override { printf("B implementation\n"); }
};

class  C : public B {
  public:
    inline void foo() final { A::foo(); }
};

int main(int argc, char **argv) {
  auto c = new C();
  c->foo();
}

一般来说,对 c->foo() 的调用是否可以去虚拟化并内联到 printf("default implementation") 调用?这是否有保证,例如在 gcc 中?我的直觉是 A::foo() 是非虚拟的,因为该类是明确指定的,因此 printf 将始终被内联。

最佳答案

你问的是优化,所以通常我们必须选择一个编译器并尝试它。我们可以查看汇编输出以确定编译器是否按照您想要的方式进行了优化。

Let's try GCC 5.2:

.LC0:
    .string "B implementation"
B::foo():
    movl    $.LC0, %edi
    jmp puts
.LC2:
    .string "default implementation"
A::foo():
    movl    $.LC2, %edi
    jmp puts
C::foo():
    movl    $.LC2, %edi
    jmp puts
main:
    subq    $8, %rsp
    movl    $8, %edi
    call    operator new(unsigned long)
    movl    $.LC2, %edi
    call    puts
    xorl    %eax, %eax
    addq    $8, %rsp
    ret

And let's try out Clang 3.6 :

main:                                   # @main
    pushq   %rax
    movl    $.Lstr, %edi
    callq   puts
    xorl    %eax, %eax
    popq    %rdx
    retq

.Lstr:
    .asciz  "default implementation"

在这两种情况下,您都可以清楚地看到所有虚函数都已内联。

“这是否有保证,例如在 gcc 中?”

如果编译器对对象的实际类型有信心,那么我怀疑这种优化总是会发生。不过,我没有任何证据支持这一说法。

关于c++ - 非 final方法去虚拟化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32720642/

相关文章:

在深度嵌套的源/makefile 中正确包含 (POSIX) 库

c++ - 一组警告作为错误 g++

c++ - 计算以下算法的复杂性?

c++ - 混合抽象类和模板,灾难的秘诀?

c++ - C++ 中的方法覆盖

c++ - 可以在 C++20 的 `decltype` 或 `sizeof` 表达式中定义类型吗?

C++ lambda 在模板的第二次扩展中没有捕获变量?

docker - Alpine 上哪个库包含 cdefs.h?

c++ - Codecvt 在 gcc 中不起作用

c++ - 我需要什么 C++ 库来编译这个程序