For record subtypes, GNAT permits the specification of the Bit_Order attribute. The specification may either correspond to the default bit order for the target, in which case the specification has no effect and places no additional restrictions, or it may be for the non-standard setting (that is the opposite of the default).
In the case where the non-standard value is specified, the effect is to renumber bits within each byte, but the ordering of bytes is not affected. There are certain restrictions placed on component clauses as follows:
These are unrestricted, and the effect is merely to renumber bits. For example if we are on a little-endian machine with Low_Order_First being the default, then the following two declarations have exactly the same effect:
type R1 is record A : Boolean; B : Integer range 1 .. 120; end record; for R1 use record A at 0 range 0 .. 0; B at 0 range 1 .. 7; end record; type R2 is record A : Boolean; B : Integer range 1 .. 120; end record; for R2'Bit_Order use High_Order_First; for R2 use record A at 0 range 7 .. 7; B at 0 range 0 .. 6; end record;
The useful application here is to write the second declaration with the Bit_Order attribute definition clause, and know that it will be treated the same, regardless of whether the target is little-endian or big-endian.
These are components that exactly fit in two or more bytes. Such component declarations are allowed, but have no effect, since it is important to realize that the Bit_Order specification does not affect the ordering of bytes. In particular, the following attempt at getting an endian-independent integer does not work:
type R2 is record A : Integer; end record; for R2'Bit_Order use High_Order_First; for R2 use record A at 0 range 0 .. 31; end record;
This declaration will result in a little-endian integer on a little-endian machine, and a big-endian integer on a big-endian machine. If byte flipping is required for interoperability between big- and little-endian machines, this must be explicitly programmed. This capability is not provided by Bit_Order.
but do not occupy an integral number of bytes. Given that bytes are not reordered, such fields would occupy a non-contiguous sequence of bits in memory, requiring non-trivial code to reassemble. They are for this reason not permitted, and any component clause specifying such a layout will be flagged as illegal by GNAT.
Since the misconception that Bit_Order automatically deals with all endian-related incompatibilities is a common one, the specification of a component field that is an integral number of bytes will always generate a warning. This warning may be suppressed using pragma Warnings (Off) if desired. The following section contains additional details regarding the issue of byte ordering.