Pragma Pack
applied to a record will pack the components to reduce
wasted space from alignment gaps and by reducing the amount of space
taken by components. We distinguish between `packable' components and
`non-packable' components.
Components of the following types are considered packable:
For all these cases, if the 'Size
value is in the range 1 through 64 on
32-bit targets, and 1 through 128 on 64-bit targets, the components occupy
the exact number of bits corresponding to this value and are packed with no
padding bits, i.e. they can start on an arbitrary bit boundary.
All other types are non-packable, they occupy an integral number of storage
units and the only effect of pragma Pack
is to remove alignment gaps.
For example, consider the record
type Rb1 is array (1 .. 13) of Boolean; pragma Pack (Rb1); type Rb2 is array (1 .. 65) of Boolean; pragma Pack (Rb2); type AF is new Float with Atomic; type X2 is record L1 : Boolean; L2 : Duration; L3 : AF; L4 : Boolean; L5 : Rb1; L6 : Rb2; end record; pragma Pack (X2);
The representation for the record X2
is as follows on 32-bit targets:
for X2'Size use 224; for X2 use record L1 at 0 range 0 .. 0; L2 at 0 range 1 .. 64; L3 at 12 range 0 .. 31; L4 at 16 range 0 .. 0; L5 at 16 range 1 .. 13; L6 at 18 range 0 .. 71; end record;
Studying this example, we see that the packable fields L1
and L2
are of length equal to their sizes, and placed at
specific bit boundaries (and not byte boundaries) to eliminate
padding. But L3
is of a non-packable float type (because
it is aliased), so it is on the next appropriate alignment boundary.
The next two fields are fully packable, so L4
and L5
are
minimally packed with no gaps. However, type Rb2
is a packed
array that is longer than 64 bits, so it is itself non-packable on
32-bit targets. Thus the L6
field is aligned to the next byte
boundary, and takes an integral number of bytes, i.e., 72 bits.