Devirtualizing a non-final method

一曲冷凌霜 提交于 2019-12-10 19:42:46

问题


Suppose I have a class setup like the following:

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();
}

In general, can the call to c->foo() be devirtualized and inlined down to the printf("default implementation") call? Is this guaranteed, for example in gcc? My intuition is that A::foo() is non-virtual because the class is specified explicitly, and so the printf will always be inlined.


回答1:


You're asking about optimizations, so in general we have to pick a compiler and try it. We can look at the assembly output to determine if the compiler is optimizing the way you want.

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"

In both cases you can see that pretty clearly that all of the virtual functions have been inlined.

"Is this guaranteed, for example in gcc?"

If the compiler is confident about what the actual type of an object is, then I suspect this optimization will always happen. I don't have anything to back up this claim though.



来源:https://stackoverflow.com/questions/32720642/devirtualizing-a-non-final-method

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!