Alignment Clauses
GNAT requires that all alignment clauses specify a power of 2, and all
default alignments are always a power of 2. The default alignment
values are as follows:
- Primitive Types
For primitive types, the alignment is the maximum of the actual size of
objects of the type, and the maximum alignment supported by the target.
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 one for long packed arrays,
or arrays whose length is not known at compile time. For short packed
arrays, which are handled internally as modular types, the alignment
will be as described for primitive 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 non-packed 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 fields are packable (see separate section on pragma Pack),
then the resulting alignment is 1.
An alignment clause may
always specify a larger alignment than the default value, up to some
maximum value dependent on the target (obtainable by using the
attribute reference System'Maximum_Alignment). The only case in which
it is permissible to specify a smaller alignment than the default value
is in the case of a record for which a record representation clause is
given. In this case, packable fields for which a component clause is
given still result in a default alignment corresponding to the original
type, but this may be overridden, since these components in fact only
require an alignment of one byte. For example, given
type v is record
a : integer;
end record;
for v use record
a at 0 range 0 .. 31;
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 since this field is placed with a
component clause, it is permissible, as shown, to override the default
alignment of the record to a smaller value.