编译器是否优化了对虚方法的非多态调用?

时间:2013-06-09 14:35:12

标签: c++ optimization polymorphism virtual inline

编译器是否优化/内联对虚拟方法的非多态调用?我的意思是当调用处于非多态上下文中时所以在编译时都知道所有内容?

1 个答案:

答案 0 :(得分:0)

  

编译器是否优化/内联对虚拟方法的非多态调用?

是的,每个体面的编译器都会这样做。

GCC和MSVC甚至在-O0 / /Od模式下执行此操作。

LIVE DEMO

#ifdef _MSC_VER
    #define NOINLINE __declspec(noinline)
#else
    #define NOINLINE __attribute__ ((noinline))
#endif

template<int>
NOINLINE void ASM_MARKER()
{
    static volatile int anti_opti = 11;
    (void)anti_opti;
}

void base();
void derived();

struct Base
{
    virtual void foo()
    {
        base();
    }
};
struct Derived: Base
{
    void foo() override
    {
        derived();
    }
};

int main()
{
    ASM_MARKER<1000>();
    Base b;
    b.foo();
    ASM_MARKER<2000>();
    Derived d;
    d.foo();
    ASM_MARKER<3000>();
    Base &r = d;
    r.foo();
    ASM_MARKER<4000>();
}

G ++ 4.8 -O0:

    call    void ASM_MARKER<1000>()
    movq    vtable for Base+16, -32(%rbp)
    leaq    -32(%rbp), %rax
    movq    %rax, %rdi
    call    Base::foo()
    call    void ASM_MARKER<2000>()
    movq    vtable for Derived+16, -16(%rbp)
    leaq    -16(%rbp), %rax
    movq    %rax, %rdi
    call    Derived::foo()
    call    void ASM_MARKER<3000>()
    leaq    -16(%rbp), %rax
    movq    %rax, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    (%rax), %rax
    movq    (%rax), %rax
    movq    -8(%rbp), %rdx
    movq    %rdx, %rdi
    call    *%rax      // <--------------- NOT OPTIMIZED
    call    void ASM_MARKER<4000>()

MSVC2010SP1 / Od:

; Line 34
    call    ??$ASM_MARKER@$0DOI@@@YAXXZ     ; ASM_MARKER<1000>
; Line 35
    lea rcx, QWORD PTR b$[rsp]
    call    ??0Base@@QEAA@XZ
; Line 36
    lea rcx, QWORD PTR b$[rsp]
    call    ?foo@Base@@UEAAXXZ          ; Base::foo
; Line 37
    call    ??$ASM_MARKER@$0HNA@@@YAXXZ     ; ASM_MARKER<2000>
; Line 38
    lea rcx, QWORD PTR d$[rsp]
    call    ??0Derived@@QEAA@XZ
; Line 39
    lea rcx, QWORD PTR d$[rsp]
    call    ?foo@Derived@@UEAAXXZ           ; Derived::foo
; Line 40
    call    ??$ASM_MARKER@$0LLI@@@YAXXZ     ; ASM_MARKER<3000>
; Line 41
    lea rax, QWORD PTR d$[rsp]
    mov QWORD PTR r$[rsp], rax
; Line 42
    mov rax, QWORD PTR r$[rsp]
    mov rax, QWORD PTR [rax]
    mov rcx, QWORD PTR r$[rsp]
    call    QWORD PTR [rax]       // <--------------- NOT OPTIMIZED
; Line 43
    call    ??$ASM_MARKER@$0PKA@@@YAXXZ     ; ASM_MARKER<4000>
相关问题