VC下typeid实现及内存布局分析

VC下typeid实现及内存布局分析

    近日在学校bbs上与人讨论C++的typeid关键字的实现问题,有人提到type_info的地址是存放在虚表的第一个位置上,颇觉得不妥,于是我在vc2003下实验了一番

    在vc下,使用typeid的时候,如果typeid施加给的类型是没有vptr的class或者根本不是class
那么汇编是
mov  dword ptr [addr],offset A `RTTI Type Descriptor' (42AD40h)
也就是编译器生成一个简单的type_info对象的表,并且在编译期静态决定下标,做一个简单查表操作。

如果typeid的操作对象是具有vptr的class,但是并不是一个引用或者指针的解引用形式,例如

A a;
typeid(a);


那么仍然仅仅会做查表操作


如果typeid的操作对象是具有vptr的class,并且是引用或者指针的解引用形式,例如

A * p =   new A;
A
& r =   * p;
typeid(
* p);
typeid(r);


那么就会调用一个叫___RTtypeid的函数,并通过某种方法来获取type_info对象
下面是___RTtypeid的反汇编,这里只列出关键的几条指令

0041213E  mov         ecx,dword ptr [inptr]    ;inptr是对象的地址
00412141   mov         edx,dword ptr [ecx]
00412143   mov         eax,dword ptr [edx - 4 ]
0041215F  mov         ecx,dword ptr [eax
+ 0Ch]
00412162   mov         dword ptr [ebp - 48h],ecx
0041216C  mov         eax,dword ptr [ebp
- 48h]


基本上等价于C语言的

int a1 = ( int )p; // p是对象的地址
int a2 =   * ( int * )a1 -   4 ;
int a3 =   * ( int * )a2 +   12 ;
int a4 =   * ( int * )a3;

 

那么从这段代码可以看出vc下type_info对象的存放位置[如下图]

VC下typeid实现及内存布局分析_第1张图片


也就虚表下标为-1的位置上存放了一个指向一个未知的表的指针(暂且将此表命名为runtime_info_table)
runtime_info_table的第4格上存放了type_info对象的地址
至于runtime_info_table里前3格上存放的是什么, 还需要再研究研究
一般来说它们全是0, 但是对于多重虚继承的类, 第二格上会是4, 可能和指针的偏移量有关.

你可能感兴趣的:(VC下typeid实现及内存布局分析)