Normally the specification of a foreign language convention for a type or an object has no effect on the chosen representation. In particular, the representation chosen for data in GNAT generally meets the standard system conventions, and for example records are laid out in a manner that is consistent with C. This means that specifying convention C (for example) has no effect.
There are four exceptions to this general rule:
If pragma Convention Fortran is specified for an array subtype, then in accordance with the implementation advice in section 3.6.2(11) of the Ada Reference Manual, the array will be stored in a Fortran-compatible column-major manner, instead of the normal default row-major order.
GNAT normally stores enumeration types in 8, 16, or 32 bits as required to accommodate all values of the type. For example, for the enumeration type declared by:
type Color is (Red, Green, Blue);
8 bits is sufficient to store all values of the type, so by default, objects
of type Color
will be represented using 8 bits. However, normal C
convention is to use 32 bits for all enum values in C, since enum values
are essentially of type int. If pragma Convention C
is specified for an
Ada enumeration type, then the size is modified as necessary (usually to
32 bits) to be consistent with the C convention for enum values.
Note that this treatment applies only to types. If Convention C is given for an enumeration object, where the enumeration type is not Convention C, then Object_Size bits are allocated. For example, for a normal enumeration type, with less than 256 elements, only 8 bits will be allocated for the object. Since this may be a surprise in terms of what C expects, GNAT will issue a warning in this situation. The warning can be suppressed by giving an explicit size clause specifying the desired size.
In C, the usual convention for boolean values, that is values used for conditions, is that zero represents false, and nonzero values represent true. In Ada, the normal convention is that two specific values, typically 0/1, are used to represent false/true respectively.
Fortran has a similar convention for LOGICAL
values (any nonzero
value represents true).
To accommodate the Fortran and C conventions, if a pragma Convention specifies C or Fortran convention for a derived Boolean, as in the following example:
type C_Switch is new Boolean; pragma Convention (C, C_Switch);
then the GNAT generated code will treat any nonzero value as true. For truth values generated by GNAT, the conventional value 1 will be used for True, but when one of these values is read, any nonzero value is treated as True.