关于VC8多继承的一个问题,是否是为实现多继承对象布局的bug?不知道是不是已经被发现了
struct _base1{};
struct _base2{};
struct _inheritance : _base1, _base2{};
int main()
{
// Ok no problem
_base1* p1 = new _inheritance;
delete p1;
// p2 now point to _base2 subobject, and the delete operator will cause error
_base2* p2 = new _inheritance;
delete p2;
return 0;
}由于VC8实现多继承的机制,第二种情况下,p2的值会为了指向_base2类型的子对象,增加了1个byte,原因是_base2在继承列表中排列顺序在后,这也是多继承的一种实现机制,Insight C++ Object Module中也早已说明。可以通过使用/d1reportAllClassLayout编译选项观察到这一点,如下:
1>class _base1 size(1):
1> +---
1> +---
1>class _base2 size(1):
1> +---
1> +---
1>class _inheritance size(1):
1> +---
1> | +--- (base class _base1)
1> | +---
1> | +--- (base class _base2)
1> | +---
1> +---
也可以通过反汇编看到:
; this is the first case, p1 point to subobject _base1 which is just the address of _inheritance and no problem
00401000 push 1
00401002 call operator new (401048h)
00401007 push eax
00401008 call operator delete (40104Eh)
; this is the 2nd case, p2 point to subobject _base2 and ...
0040100D push 1
0040100F call operator new (401048h)
00401014 add esp,0Ch
00401017 test eax,eax
00401019 je wmain+2Ah (40102Ah)
0040101B add eax,1 ; here, for multi inheritance, the point add an offset of 1 to subobject _base2
0040101E push eax
0040101F call operator delete (40104Eh) ; and, the call to operator delete will cause error, the free failed.因为观察到以上现象,很容易观察到是按照继承列表顺序,所以,试验了下面的情况
struct _inheritance : _base1, _base2, _base3 {};
_base3* p3 = new _inheritance;
delete p3;果然也是这样。
多继承一直是C++实现的一个问题,所以,我猜测其他编译器也许有类似的或者其他问题,于是对GCC进行了测试,但是,GCC在这一点上没有问题。
...全文


工具平台和程序库
