|
Boost : |
Subject: Re: [boost] [optional] memory use for optional refs and ptrs
From: Sebastian Redl (sebastian.redl_at_[hidden])
Date: 2010-10-07 09:03:32
On 07.10.2010 13:22, Stewart, Robert wrote:
> That's not what I was suggesting. short can have alignment requirements, but bool and char do not. I was suggesting that this:
>
> struct P
> {
> short s;
> char c;
> short t;
> char d;
> };
>
> could occupy less space than if the chars and shorts were reversed. That is, that
> P::c could occupy padding between P::s and P::t and P::d could occupy padding between a P instance and something following it in another composite. Doing so would not violate an ABI, unless the ABI specifically disallowed it, because it can be established as the expected layout in those cases.
>
True, but that requires a type where alignof(T) > sizeof(T), which only
happens if you override alignment requirements with attributes or
something similar. Which aligned_storage actually wouldn't understand.
(Such types are dangerous anyway. VC++, at least, doesn't actually
guarantee proper alignment for every instance of such a type, in
particular not for members of an array of such type.)
But you're missing my point. The whole exercise is useless. For layout
purposes, boost::optional is a struct containing two members. It can be
written either as { T t; bool b; } or { bool b; T t; }. Assuming
alignof(bool) == sizeof(bool) == 1 (which is actually not the case in
some old ABIs), it holds true in both cases that alignof(optional) ==
alignof(T) and sizeof(optional) == 2 * sizeof(T).
Because layout algorithms treat member types as opaque, it doesn't
matter where the padding in optional is - no compiler will embed members
of a containing struct in the padding of the optional.
Let me give you an example. Here's a struct that actually shrinks if you
reorder the members:
struct A {
char c1;
int i;
char c2;
}; // sizeof == 12
struct A_Opt {
int i;
char c1;
char c2;
}; // sizeof == 8
But this only works because all members are top-level. Contained structs
are opaque! This means that if I change A_Opt to pack the first two
members together, the size optimization is lost!
struct A_Bad {
struct {
int i;
char c1;
} bad;
char c2;
}; // sizeof == 12
This is exactly the problem you face when trying to optimize optional.
It doesn't matter that you move the padding to the end of the struct.
The compiler still won't use it.
Examples validated with Visual Studio 2010.
Sebastian
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk