Pragma Pack for Records (GNAT Reference Manual)

### 9.11 Pragma Pack for Records ¶

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:

- Components of an elementary type are packable unless they are aliased, independent or atomic.
- Small packed arrays, where the size is statically known, are represented internally as modular integers, and so they are also packable.
- Small simple records, where the size is statically known, are also 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.