Alignment Clauses (GNAT Reference Manual)

### 10.1 Alignment Clauses ¶

GNAT requires that all alignment clauses specify 0 or a power of 2, and all default alignments are always a power of 2. Specifying 0 is the same as specifying 1.

The default alignment values are as follows:

- ‘Elementary Types’.

  For elementary types, the alignment is the minimum of the actual size of objects of the type divided by `Storage_Unit`, and the maximum default alignment supported by the target. (This maximum default alignment is given by the GNAT-specific attribute `Standard'Maximum_Alignment`; see Attribute Maximum_Alignment.)

  For example, for type `Long_Float`, the object size is 8 bytes, and the default alignment will be 8 on any target that supports alignments this large, but on some targets, the maximum alignment may be smaller than 8, in which case objects of type `Long_Float` will be maximally aligned.

- ‘Arrays’.

  For arrays, the alignment is equal to the alignment of the component type for the normal case where no packing or component size is given. If the array is packed, and the packing is effective (see separate section on packed arrays), then the alignment will be either 4, 2, or 1 for long packed arrays or arrays whose length is not known at compile time, depending on whether the component size is divisible by 4, 2, or is odd. For short packed arrays, which are handled internally as modular types, the alignment will be as described for elementary types, e.g. a packed array of length 31 bits will have an object size of four bytes, and an alignment of 4.

- ‘Records’.

  For the normal unpacked case, the alignment of a record is equal to the maximum alignment of any of its components. For tagged records, this includes the implicit access type used for the tag. If a pragma `Pack` is used and all components are packable (see separate section on pragma `Pack`), then the resulting alignment is 1, unless the layout of the record makes it profitable to increase it.

  A special case is when:

  - the size of the record is given explicitly, or a full record representation clause is given, and
  - the size of the record is 2, 4, or 8 bytes.

  In this case, an alignment is chosen to match the size of the record. For example, if we have:

      type Small is record
         A, B : Character;
      end record;
      for Small'Size use 16;

  then the default alignment of the record type `Small` is 2, not 1. This leads to more efficient code when the record is treated as a unit, and also allows the type to specified as `Atomic` on architectures requiring strict alignment.

An alignment clause may specify a larger alignment than the default value up to some maximum value dependent on the target. It may also specify a smaller alignment than the default value for enumeration, integer and fixed point types, as well as for record types, for example

    type V is record
       A : Integer;
    end record;

    for V'alignment use 1;

The default alignment for the type `V` is 4, as a result of the Integer field in the record, but it is permissible, as shown, to override the default alignment of the record with a smaller value.

Note that according to the Ada standard, an alignment clause applies only to the first named subtype. If additional subtypes are declared, then the compiler is allowed to choose any alignment it likes, and there is no way to control this choice. Consider:

    type R is range 1 .. 10_000;
    for R'Alignment use 1;
    subtype RS is R range 1 .. 1000;

The alignment clause specifies an alignment of 1 for the first named subtype `R` but this does not necessarily apply to `RS`. When writing portable Ada code, you should avoid writing code that explicitly or implicitly relies on the alignment of such subtypes.

For the GNAT compiler, if an explicit alignment clause is given, this value is also used for any subsequent subtypes. So for GNAT, in the above example, you can count on the alignment of `RS` being 1. But this assumption is non-portable, and other compilers may choose different alignments for the subtype `RS`.