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

[yc]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,并且是引用或者指针的解引用形式,例如

* =   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对象的存放位置[如下图]

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


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

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