Free Pascal supports fixed records and records with variant parts. The syntax diagram for a record type is
_________________________________________________________________________________________________________
Record types
___________________________________________________________________
So the following are valid record type declarations:
The variant part must be last in the record. The optional identifier in the case statement serves to access the tag field value, which otherwise would be invisible to the programmer. It can be used to see which variant is active at a certain time3. In effect, it introduces a new field in the record.
Remark It is possible to nest variant parts, as in:
When initializing a variable (or constant) of type record, a special syntax must be used: for each field in the record, the name must be specified, followed by a colon and an expression for the field value. The compiler must be able to evaluate the expression at compile time. The values of the field are separated by a semicolon.
_________________________________________________________________________________________________________
Constant record value
___________________________________________________________________
For the MyRec record above, the following would initialize all fields:
You do not need to specify values for all fields, but then the compiler will warn you. The following is a valid initialization:
But it results in a warning:
The layout and size of a record is influenced by five aspects:
The layout and size of variant parts in records is determined by replacing them with a field whose type is a record with as first element a field of the tag field type if an identifier was declared for this tag field, followed by the elements of the biggest variant.
Field F2’s offset in a record is equal to the sum of the previous field F1’s offset and F1’s size, rounded up to a multiple of F2’s required alignment. This required alignment is calculated as follows:
The size of a record is equal to the sum of the record’s last field’s offset and this field’s size, rounded up to a multiple of the record’s required alignment. The record’s required alignment is calculated as follows:
Free Pascal also supports a “packed record”, which is a record where all the elements are byte-aligned. As a result, the two following declarations are equivalent:
and
Note the {$PackRecords Default} after the first declaration to restore the default setting!
Given the platform-dependent nature of how records are laid out in memory, the only way to ensure a compatible layout across platforms (assuming that all fields are declared using a type with the same meaning across these same platforms) is by using {$PACKRECORDS 1}.
In particular, if a typed file with records, produced by a Turbo Pascal program, must be read, then chances are that attempting to read that file correctly will fail. The reason is that Free Pascal’s default {$PACKRECORDS N} setting is not necessarily compatible with Turbo Pascal’s. It can be changed to {$PACKRECORDS 1} or {$PACKRECORDS 2} depending on the setting used in the Turbo Pascal program that create the file (although it may still fail with {$PACKRECORDS 2} due to different type alignment requirements between 16 bit MSDOS and your current platform).
The same remark goes for Delphi: exchanging data is only guaranteed to be possible if both the producer and consumer use a packed record, or if they are on the same platform and use the same {$PACKRECORDS X} setting.
3However, it is up to the programmer to maintain this field.