私はこの非常に単純な C++ プログラムを作成しましたが、コンパイラが vtable を 2 つのポインター逆参照にまたがって配置する理由が気になりました。C++ プログラムは次のとおりです。
class Foo {
public:
virtual void bar() {
}
};
int main(int argc, char *arv[]) {
Foo foo;
Foo *foo_p(&foo);
foo_p->bar();
}
ここで、コンパイラによって生成されたアセンブリを確認できます。
$ g++ -ggdb -Wall -O0 -S test.cpp
関連するセクションは次のとおりです。
.loc 1 9 0
leaq -16(%rbp), %rax # put the address of 'foo' in %rax
movq %rax, %rdi # use it as the first argument of the following function
call _ZN3FooC1Ev # call the Foo constructor
.loc 1 10 0
leaq -16(%rbp), %rax # put the address of 'foo' in %rax
movq %rax, -24(%rbp) # create 'foo_p' on the stack
.loc 1 11 0
movq -24(%rbp), %rax # load 'foo_p' into %rax
movq (%rax), %rax # dereference the pointer, put it in %rax
# %rax now holds the hidden pointer in 'foo', which is the vtable pointer
movq (%rax), %rdx # dereference the pointer ::again:: (with an offset of 0), put it in %rdx
# %rdx now holds a function pointer from the vtable
movq -24(%rbp), %rax # create the 'this' pointer (== foo_p) and put it in %rax
movq %rax, %rdi # use the 'this' pointer as the first argument to the following function
call *%rdx # call Foo::bar (via the vtable)
2 番目のポインター逆参照が必要なのはなぜですか? オブジェクトの「隠された」vtable ポインタが vtable を直接指していないのはなぜですか?
編集: ::is:: vtable を直接指しています。私はポインタと混同しました:-P