From Bugzilla Helper: User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0) Description of problem: Here is the small testcase attached that shows the problem. In words, we have: class C2 { public: ptrdiff_t a; int b; }; This class will get alignment of 8 bytes. It means that there should be 4 extra padding bytes at the end of the class object, after member int x_ which size is only 4 bytes; In practice it is. class D : public C2 { public: virtual void foo () {} int x_; }; The situation here is that C2::x_ member inside the class D object loses its alignment, those 4 padding bytes disappeared, instead of them we see the D::x_ member. So, the alignment of whole class is correct, but such layout violates the C++ ABI (http://www.codesourcery.com/cxx-abi/abi.html#layout) which says : --- For non-POD class types C, assume that all component types (i.e. proper base classes and non-static data member types) have been laid out, defining size, data size, non-virtual size, alignment, and non-virtual alignment. --- i.e. layout of C2 members should be permanent whenever C2 is used as base or not. So, the result should like: those padding bytes for C2::x_ should be left, D::x_ should be also padded to make class D alignment equal to 8. Version-Release number of selected component (if applicable): How reproducible: Always Steps to Reproduce: Compile attached testcase with g++3 and run it. Actual Results: Testcase output: Part 0 - Passed Part 1,2 - Failed Expected Results: Testcase output: Part 0,1,2 - Passed Additional info:
Created attachment 56524 [details] Testcase
As I can see, the actuall reason of this failure is that the G++ does not perform finalization step when processing class C2. As a result we see the wrong class layout. --- C++ ABI ----------------- Chapter 2: Data Layout 2.4 Non-POD Class Types ... IV. Finalization Round sizeof(C) up to a non-zero multiple of align(C). ----------------------------- This happens for base classes only. If you make D's data member of type C2 you'll see it correctly finalized and paded.
3.2 g++ correctly warns about the pointer abuse vp1test.cpp: In function `int main()': vp1test.cpp:46: warning: invalid offsetof from non-POD type `class D'; use pointer to member instead
True that the offsetof abuse is incorrect, but it's also true that the layout problem has been fixed in gcc 3.2. The test case does run Part 0 - Passed Part 1 - Passed Part 2 - Passed and gdb confirms that the layout of a variable of type D (gdb) p d $1 = {<C2> = {a = 0, b = 0}, _vptr.D = 0x0, x_ = 0} (gdb) p sizeof(d) $2 = 32