I would like to be able to predict what will be in the resulting binary when I call Write in Ada to serialize a record. Do you know where I can look this up?
I have some legacy Ada software that produces a binary file by Write-ing a record, and I need to debug a C++ program that is supposed to write a compatible binary file. So, I would like to understand what rules Ada follows when it serializes a record, so that I can make sure that the C++ code will produce a functionally equivalent record.
Basically, the compiler will reorder the components of your record types, unless you use the pragma PACK or the pragma PRESERVE_LAYOUT commands with your record types. Also, the compiler will pad objects to maintain the alignment of record components. Components follow:
Integer: 8, 16, or 32 bit twos-complement signed numbers
Float: 32-bit IEEE format
Long_Float: 64-bit IEEE format
Fixed-Point: 8, 16, or 32 bit; however, the range and delta specified can affect being 16 or 32
Enumerations: Integer, usually first element is represented by 0
Booleans: Enumeration object, 8 bits long, The LSB stores the value: 0 = false, 1 = true
Characters: Enumeration object, 8 bits long, unsigned 0 through 127
Access Types: 32 bits, 32-bit value of 0 represents NULL
Arrays: stored contiguously in row-major order, size depends on base type. The array is padded to ensure all elements have the proper alignment for their types.
The format of the serialised output of 'Write has absolutely nothing to do with representation clauses.
By default, the compiler will output record components without alignment padding in the order in which they're written in the record declaration, using a translation scheme that isn't defined by the standard (so you may not get interoperability between compilers). GNAT (the GCC Ada compiler) outputs each component in a whole number of bytes.
If you want to stream values of a type using some different format, you can override 'Write for the type. As an unusual example, you could stream to XML.
As mentioned by others, without additional instruction the compiler will make its own decisions about record layout. The best approach would be to change the original code to write the record using a specific layout. In particular, the record representation clause allows the Ada programmer to specify exactly the physical layout for a record. In fact, you should check to see whether the original code has one of these for the type in question. If it does, then this would answer your question precisely.
The Ada95 Language Reference Manual says (section 13.13.2):
"For elementary types, the representation in terms of stream elements is implementation defined. For composite types, the Write or Read attribute for each component is called in a canonical order. The canonical order of components is last dimension varying fastest for an array, and positional aggregate order for a record."
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With