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