2月
26
C++11 には仮想関数をそれ以上オーバーライドできないようにする final という指定が書けますが、final が付いていると呼ぶときに vtable を参照して間接callするのではなく直接呼ぶようになります。(とりあえず GCC の場合)
[umezawa@umezawa-cent7:pts/0 ~]$ cat a.cc struct A { virtual void foo(); }; struct B : public A { virtual void foo() final; }; struct C : public A { virtual void foo(); }; void bar(B* b) { b->foo(); } void baz(C* c) { c->foo(); } [umezawa@umezawa-cent7:pts/0 ~]$ g++ -std=c++11 -S -o- -O0 a.cc .file "a.cc" .text .globl _Z3barP1B .type _Z3barP1B, @function _Z3barP1B: .LFB0: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movq %rdi, -8(%rbp) movq -8(%rbp), %rax movq %rax, %rdi call _ZN1B3fooEv leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size _Z3barP1B, .-_Z3barP1B .globl _Z3bazP1C .type _Z3bazP1C, @function _Z3bazP1C: .LFB1: .cfi_startproc pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $16, %rsp movq %rdi, -8(%rbp) movq -8(%rbp), %rax movq (%rax), %rax movq (%rax), %rax movq -8(%rbp), %rdx movq %rdx, %rdi call *%rax leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE1: .size _Z3bazP1C, .-_Z3bazP1C .ident "GCC: (GNU) 4.8.5 20150623 (Red Hat 4.8.5-16)" .section .note.GNU-stack,"",@progbits
興味深いのは最適化なしでもそうなるという点でしょうか。
直接呼ばれるとシンボルを参照するようになるため、リンク順でハマるケースがあるかもしれません。
no comment untill now