Next: , Previous: Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc., Up: BP Incompatibilities



7.2.11 Endianness assumptions

GPC also runs on big-endian systems (see Endianness). This is, of course, a feature of GPC, but might affect your programs when running on a big-endian system if they make assumptions about endianness, e.g., by using type casts (or absolute declarations or variant records misused as type casts) in certain ways. Please see the demo program absdemo.pas for an example and how to solve it.

Endianness is also relevant (the more common case) when exchanging data between different machines, e.g. via binary files or over a network. Since the latter is not easily possible in BP, and the techniques to solve the problems are mostly the same as for files, we concentrate on files here.

First, you have to choose the endianness to use for the file. Most known data formats have a specified endianness (usually that of the processor on which the format was originally created). If you define your own binary data format, you're free to choose the endianness to use.

Then, when reading or writing values larger than one byte from/to the file, you have to convert them. GPC's Run Time System supports this by some routines. E.g., you can read an array from a little-endian file with the procedure BlockReadLittleEndian, or write one to a big-endian file with BlockWriteBigEndian. Note: The endianness in the procedure names refers to the file, not the system – the routines know about the endianness of the system they run on, but you have to tell them the endianness of the file to use. This means you do not have to (and must not) use an ifdef to use the version matching the system's endianness.

When reading or writing records or other more complicated structures, either read/write them field by field using BlockReadBigEndian etc., or read/write them with the regular BlockRead and BlockWrite procedures and convert each field after reading or before writing using procedures like ConvertFromBigEndian or ConvertToLittleEndian (but remember, when writing, to undo the conversion afterwards, if you want to keep using the data – this is not necessary with BlockWriteLittleEndian etc.).

Especially for strings, there are ready-made procedures like ReadStringBigEndian or WriteStringLittleEndian which will read/write the length as a 64 bit value (much space for really long strings :−) in the given endianness, followed by the characters (which have no endianness problem).

All these routines are described in detail in the RTS reference (see Run Time System), under endianness. The demo program endiandemo.pas contains an example on how to use these routines.