コンパイラは、仮想メソッドへの非ポリモーフィック呼び出しを最適化/インライン化しますか? つまり、呼び出しが非ポリモーフィックなコンテキストにある場合、コンパイル時にすべてが認識されるということですか?
user2341104
質問する
461 次
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 に答える