1

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

4

1 回答 1

0

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

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

GCC 和 MSVC 甚至在-O0//Od模式下也能做到这一点。

现场演示

#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>
于 2013-07-10T18:43:26.670 回答