Tail padding, again

Mark Mitchell mark at codesourcery.com
Thu Oct 19 18:29:18 UTC 2000


I think I recall that the committee was intentionally trying to use
the tail padding of one object to save space.  For example, consider:

  struct A { short s; char c; };
  struct B { A a; char d; };

(These are PODs, but you can easily make an equivalent non-POD example).

Here, I think the comittee wanted to give `B' size 4, by packing `d'
into the tail padding of `A'.

I think this is a mistake.  David Gross came up with the following
example:

  - Code generator needs to copy dsize, not sizeof, unless it can prove
    that the object is in a context where tail padding isn't overlayed.
    Reason?  Tail padding might be overlayed by a volatile field.

    Hence, a non-POD that looks like

      struct S { short sh; char ch; };

    requires ld2/st2/ld1/st1 for a copy instead of ld4/st4 because we
    might have

      struct T { S s; volatile char d; };

Similarly, people using memcpy to copy around POD components of
non-PODs will get burned.

This completely breaks user expectation since people routinely expect
to be able to stick a function or two into a POD without changing its
layout.

I think we should make the following changes:

  - Make nvsize a multiple of nvalign.  That ensures that we don't
    have odd sub-components that we can't copy around easily.

  - Allocate `sizeof' bytes for a data member, and `nvsize' bytes for
    a base class when laying out an object.

Note that this still permits the empty base optimization; nvsize will
be zero, and sizeof will be 1.

There's an important different between using the tail padding in an
empty base and the tail padding in a generic object: you know that you
never have to copy an empty base.

--
Mark Mitchell                   mark at codesourcery.com
CodeSourcery, LLC               http://www.codesourcery.com




More information about the cxx-abi-dev mailing list