How to layout the class (with bitfield members) in the inheritance hierarchy on GCC 3.3
Yan Shi
yanshi at ca.ibm.com
Tue Jun 1 15:57:58 UTC 2004
Hi,
According to C++ ABI 2.4 Non-POD Class Types defintion:
"Allocation of Members Other Than Virtual Bases
For each data component D (first the primary base of C, if any, then the
non-primary, non-virtual direct base classes in declaration order, then the
non-static data members in declaration order), allocate as follows:
If D is a bitfield, i.e. declared as "T [b]: n;", for some integral POD
type T and bit count n:
There are two cases depending on sizeof(T) and n:
If sizeof(T)*8 >= n, the bitfield is allocated as required by the
underlying C psABI. That is, it will be placed in the next available n
bits, subject to the constraint that it does not cross an alignment
boundary for type T.
If dsize(C) > 0, and the byte at offset dsize(C) - 1 is partially filled by
a bitfield, and that bitfield is also a data member declared in C (but not
in one of C's proper base classes), the next available bits are the
unfilled bits at offset dsize(C) - 1. Otherwise, the next available bits
are at offset dsize(C).
Update align(C) to max (align(C), align(T)). "
For the following test cases, the bitfield members (b0, b1, b2, b3, b4),
should all be allocated together in 4 bytes, therefore the total size of
struct B4 (test2.C) should be 8 bytes and the alignment of struct B4 is 4
bytes.
However, I tried both test cases with GCC 3.3 on SLES9 Linux, the size of
struct B4 (test2.C) is 12 bytes, while the alignment of struct B4 is 4
bytes on 32-bit mode, which does not agree with the ABI definition. Could
some one please explain what the rules/algorithm for such behavior in GCC
3.3?
Here are the attached test cases, actual/expected struct layout, and my
observations:
|-------+---------------------------------+-------------------------------|
| | test.C | test2.C |
|-------+---------------------------------+-------------------------------|
|test |struct B0 { |struct B0 { |
|cases | int b0 :1; | virtual void foo() {}; |
| |}; |<===== with vft table |
| |struct B1 : public B0 { | int b0 :1;; |
| | int b1 :10; |}; |
| |}; |struct B1 : public B0 { |
| | | int b1 :10; |
| |struct B2 : public B1 { |}; |
| | int b2 :1; | |
| |}; |struct B2 : public B1 { |
| | | int b2 :1; |
| |struct B3 : public B2 { |}; |
| | int b3 :1; | |
| |}; |struct B3 : public B2 { |
| | | int b3 :1; |
| |struct B4 : public B3 { |}; |
| | int b4 :6; | |
| |}; |struct B4 : public B3 { |
| | | int b4 :1; |
| |(See attached file: test.C) |}; |
| | |(See attached file: test2.C) |
|-------+---------------------------------+-------------------------------|
|Dump |--b4.b0--- dumping 12 bytes----- |--b4.b0--- dumping 12 |
|struct |10000000 00000000 00000000 |bytes----- |
|B4 |00000000 |00000000 00000000 00000000 |
|member |00000000 00000000 00000000 |00000000 |
|layout |00000000 |10000000 00000000 00000000 |
| |00000000 00000000 00000000 |00000000 |
|on |00000000 |00000000 00000000 00000000 |
|32-bit | |00000000 |
|mode |--b4.b1--- dumping 12 bytes----- | |
| |00000000 00000000 00000000 |--b4.b1--- dumping 12 |
|(GCC |00000000 |bytes----- |
|3.3 |11111111 11000000 00000000 |00000000 00000000 00000000 |
|ouput) |00000000 |00000000 |
| |00000000 00000000 00000000 |01111111 11100000 00000000 |
| |00000000 |00000000 |
| | |00000000 00000000 00000000 |
| |--b4.b2--- dumping 12 bytes----- |00000000 |
| |00000000 00000000 00000000 | |
| |00000000 |--b4.b2--- dumping 12 |
| |00000000 00100000 00000000 |bytes----- |
| |00000000 |00000000 00000000 00000000 |
| |00000000 00000000 00000000 |00000000 |
| |00000000 |00000000 00010000 00000000 |
| | |00000000 |
| |--b4.b3--- dumping 12 bytes----- |00000000 00000000 00000000 |
| |00000000 00000000 00000000 |00000000 |
| |00000000 | |
| |00000000 00000000 00000000 |--b4.b3--- dumping 12 |
| |10000000 |bytes----- |
| |00000000 00000000 00000000 |00000000 00000000 00000000 |
| |00000000 |00000000 |
| | |00000000 00000000 00000000 |
| |--b4.b4--- dumping 12 bytes----- |10000000 |
| |00000000 00000000 00000000 |00000000 00000000 00000000 |
| |00000000 |00000000 |
| |00000000 00000000 00000000 | |
| |01111110 |--b4.b4--- dumping 12 |
| |00000000 00000000 00000000 |bytes----- |
| |00000000 |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |01000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
|-------+---------------------------------+-------------------------------|
|Dump |the same as the output on 32-bit |--b4.b0--- dumping 16 |
|struct |mode |bytes----- |
|B4 | |00000000 00000000 00000000 |
|member | |00000000 |
|layout | |00000000 00000000 00000000 |
| | |00000000 |
|on | |10000000 00000000 00000000 |
|64-bit | |00000000 |
|mode | |00000000 00000000 00000000 |
| | |00000000 |
|(GCC | | |
|3.3 | |--b4.b1--- dumping 16 |
|ouput) | |bytes----- |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |01111111 11100000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | | |
| | |--b4.b2--- dumping 16 |
| | |bytes----- |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00010000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | | |
| | |--b4.b3--- dumping 16 |
| | |bytes----- |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |10000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | | |
| | |--b4.b4--- dumping 16 |
| | |bytes----- |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00000000 00000000 |
| | |01000000 |
| | |00000000 00000000 00000000 |
| | |00000000 |
|-------+---------------------------------+-------------------------------|
|Observa| (1) it cannot put more than two |the same observation as test.C |
|tion |bit fields from different classes| |
| |in a byte. | |
| | (2) if previous bits exactly fit| |
| |the byte container (all 8 bits | |
| |are used, no remaining free | |
| |bits), then pad the following | |
| |bits that is from different | |
| |classes tightly | |
| |(3) else, pad the following bits | |
| |that is from different classes | |
| |one byte after the previous | |
| |bit-ending byte (vacate one byte)| |
| |(4) Question: why vacate last | |
| |4-byte in struct B4 (useless | |
| |padding)? | |
|-------+---------------------------------+-------------------------------|
|Suggest|--b4.b0--- dumping 4 bytes----- |--b4.b0--- dumping 8 bytes-----|
|ed |10000000 00000000 00000000 |00000000 00000000 00000000 |
|layout |00000000 |00000000 |
|on | |10000000 00000000 00000000 |
|32-bit |--b4.b1--- dumping 4 bytes----- |00000000 |
|mode |01111111 11100000 00000000 | |
| |00000000 |--b4.b1--- dumping 8 bytes-----|
| | |00000000 00000000 00000000 |
| |--b4.b2--- dumping 4 bytes----- |00000000 |
| |00000000 00010000 00000000 |01111111 11100000 00000000 |
| |00000000 |00000000 |
| | | |
| |--b4.b3--- dumping 4 bytes----- |--b4.b2--- dumping 8 bytes-----|
| |00000000 00001000 00000000 |00000000 00000000 00000000 |
| |00000000 |00000000 |
| | |00000000 00010000 00000000 |
| |--b4.b4--- dumping 4 bytes----- |00000000 |
| |00000000 00000111 11100000 | |
| |00000000 |--b4.b3--- dumping 8 bytes-----|
| | |00000000 00000000 00000000 |
| | |00000000 |
| | |00000000 00001000 00000000 |
| | |00000000 |
| | | |
| | |--b4.b4--- dumping 4 bytes-----|
| | |00000000 00000111 11100000 |
| | |00000000 |
|-------+---------------------------------+-------------------------------|
Your reply will be appreciated.
Best regards,
Yan (Barbara) Shi
C++ Front End and Runtime Development
Email: yanshi at ca.ibm.com
Tel: (905) 413-3813 Tie: 969-3813 Location: C2/KD2/8200/MKM
IBM Toronto Laboratory, 8200 Warden Ave, Markham, Ontario, Canada L6G 1C7
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test.C
Type: application/octet-stream
Size: 1537 bytes
Desc: not available
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20040601/498cff76/attachment.obj>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: test2.C
Type: application/octet-stream
Size: 1567 bytes
Desc: not available
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20040601/498cff76/attachment-0001.obj>
More information about the cxx-abi-dev
mailing list