[cxx-abi] [cxx-abi-dev] Tail padding, in sumary

Mark Mitchell mark at codesourcery.com
Tue Aug 27 18:19:02 UTC 2002


Here are patches to the ABI document that, I believe, clarify the
issues recently raised on the ABI list.  Most of these are clarifications,
but point (5) below is substantive and you should look at it carefully.

I will check these in after 48 hours, unless I receive comments to the
contrary.

I have attached both diffs and the patched HTML file for your convenience.

Here is a summary of the changes:

0. Move "morally virtual" into the definitions section.

1. Clarify definition of nearly empty class.

   Use "direct" base classes rather than "proper" base classes, more
   carefully delineate the set of empty base classes whose offsets
   matter.

2. Simplify the descriptions of dsize, nvsize, nvalign to avoid confusion.

3. Remove allocation rules for primary base, instead using the ordinary
   rules for allocating base classes.

   This is not meant to imply that the layout of any class is changing;
   only the way things are expressed in the document.  We had separate
   language saying how you place the primary base, and it was incorrect;
   in particular it said that you set sizeof(C) to sizeof(B) [where C
   is the derived class and B the primary base] after placing the primary
   base.  You should instead set sizeof(C) to nvsize(B).  By using the
   same rules as for other bases, we avoid this problem and any other
   similar problems that might arise in the future.

4. Clarify when bit-field tail-padding can and cannot be used.

5. Change the algorithm for setting nvsize(C).

   The old version set nvsize(C) to the least multiple of nvalign(C)
   that was greater than or equal to dsize(C).  This rounding prevented
   the use of tail-padding, which was not the intent of the ABI, nor
   was it the practice of the compilers attempting to implement the ABI.

   The new version sets nvsize(C) to sizeof(C).  Note that dsize(C) would
   be another option, but that adds additional complexity.  In particular,
   if dsize(C) were used, we would lose track of empty bases allocated
   beyond dsize(C).

   Instead, we could introduce ndsize, so that we could use this
   algorithm for placing a base to this:

     Set dsize(C) to offset(D) + ndsize(D).
     Set sizeof(C) to max(sizeof(C), offset(D) + nvsize(D)).

   This is logical enough, but I think we have enough complexity as it
   is.

   Here is a test program that will verify whether or not the approach
   I took corresponds to your compiler:

     extern "C" void printf (const char*, ...);

     struct S1 {};
     struct S2 : public S1 {};
     struct S3 : public S1, public S2 { char c1; };
     struct S4 : public S3 {
      char c2;
     };

     int main () {
       printf ("sizeof (S4) == %d\n", sizeof (S4));
     }

   The point is that in S3, S1 will be placed at offset 0, S2 at offset
   1, and c1 at offset 0.  Thus dsize(S3) will be 1, sizeof(S3) will be
   2.  If your compiler is using the formulation I propose, then nvsize(S3)
   will be 2.  Therefore, S4::c2 will be placed at offset 2, and sizeof(S4)
   will be 3.  If, instead, your compiler has the notion of ndsize, it
   will place S4::c2 at offset 1, and sizeof(S4) will be 2.

   The bottom line is that if your compiler outputs 3, you should be happy
   with what I wrote.  For reference, GCC 3.2 outputs 3.

-- 
Mark Mitchell                mark at codesourcery.com
CodeSourcery, LLC            http://www.codesourcery.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: diffs
Type: application/octet-stream
Size: 9337 bytes
Desc: not available
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20020827/9e0a65c1/attachment.obj>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://sourcerytools.com/pipermail/cxx-abi-dev/attachments/20020827/9e0a65c1/attachment.html>


More information about the cxx-abi-dev mailing list