What exactly does "pragma Convention(Convention => C)" do when applied to a
record type?
It means that record types will be laid out the way C expects them to be,
whatever that is.
C preserves the order of members within a struct and inserts padding so that
members will be aligned on the machine-dependent proper address boundary for
their type.
On machines that support misaligned data (as Intel x86 machines do), the C
compilers generally have options that control alignment. To use pragma
Convention on such machines, you have to be sure that the C compiler is
invoked so as to use the same alignment that pragma Convention produces.
For simple cases, pragma Convention works fine, as long as you know that
the C compiler is observing the same alignment constraints.
You need rep specs to handle tricky and unusual cases such as:
* Mapping Ada record types with a discriminant and a variant part onto
C unions. This can be made to work as long as the C type has a member
that can serve as the discriminant; most sensibly designed C code does.
* Interfacing to C code that was compiled with a different alignment con-
vention than the one pragma Convention observes. It may take some ex-
perimentation to figure out what alignment was actually used, if you
have to interface to a commercial C library that isn't supplied with
source code.
* Preserving Ada 83 compatibility, as Ada 83 doesn't have pragma Convention.
If you use rep specs, you should not need pragma Convention, and vice versa.
Whatever you do, the interface between Ada and C is a fertile source of
errors, and we belt-and-suspenders types like to write extra tests to
check the as-compiled layout of objects passed through this interface.
|