From the relevant documentation:
pack
takes effect at the first struct
, union
, or class
declaration after the pragma is seen. pack
has no effect on definitions.
header
is a member definition, so it isn't affected.
it was declared as part of the outer declaration, would it be subject to the packing then?
Yes, as it would be a struct
declaration.
Also, as Lightness Races in Orbit remarks in a comment, a more convincing wording can be found immediately before:
To pack a class is to place its members directly after each other in memory.
i.e. it says nothing about what those members themselves contain, which may be data and/or padding. The fact that (as explored above) packedness is attached to a type would seem to reinforce that
Still, the documentation is vague enough, so it's best to test that this interpretation is correct; both gcc and VC++ behave as expected. Not that I'm particularly surprised - anything different would break havoc in the type system (taking a pointer to a member of a packed structure would actually provide a pointer to something different than its type says1).
The general idea is: once you finish defining a struct
, its binary layout is fixed, and any of its instantiations will conform to it, including subobjects of packed structures. The current #pragma pack
value is considered only when defining new structures, and when doing so the binary layout of the members is a fixed black box.
Notes
To be honest, this is a bit of an x86-centric view; machines with stronger alignment requirements would object that even pointers to layout-correct but misaligned structures aren't kosher: although the offsets of fields relative to the given pointer are correct, they aren't really pointers that can be used as they are.
OTOH, given a pointer to an unaligned object you can always detect that it's unaligned and memcpy
it to a correctly-aligned location, so it's not as bad as a hypothetical pointer to a packed object, whose layout is effectively unknown unless you happen to know the packing of its parent.