一般来说因为对齐的关系,函数地址都至少是4字节对齐的。即函数地址的最低位两个bit总是0。虽然和我的观察略微有不同(在我编译的程序里,Point::x的地址是0x8000a86,只有最后一位是0,倒数第二位是1),但也说明了函数地址确实是有对齐这一现象的。
GCC对于成员函数指针统一使用下面的结构进行表示:这篇博客里还介绍了MSVC对于成员函数指针的实现,使用了thunk技术,大家可以去看一下。(其实这个在《深度探索C++对象模型》,里也有提到,大家感兴趣也可以看看原书)。不管是普通成员函数,还是虚成员函数,信息都记录在__pfn。一般来说因为对齐的关系,函数地址都至少是4字节对齐的。即函数地址的最低位两个bit总是0。 GCC充分利用了这两个bit。如果是普通的函数,__pfn记录函数的真实地址,最低位两个bit就是全0,如果是虚成员函数,最后两个bit不是0,剩下的30bit就是虚成员函数在函数表中的索引值。复制代码
- struct
- {
- void* __pfn; //函数地址,或者是虚拟函数的index
- long __delta; // offset, 用来进行this指针调整
- };
// 注意,在我的版本里(g++ (Ubuntu 7.5.0-3ubuntu1~18.04) 7.5.0),检查的是随后一位,函数地址也只是2对齐,而不是4对齐
GCC先取出函数地址最低位两个bit看看是不是0,若是0就使用地址直接进行函数调用。若不是0,就取出前面30位包含的虚函数索引,通过计算得到真正的函数地址,再进行函数调用。
欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) | Powered by Discuz! X3.4 |