
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