Node:Endianness assumptions, Next:- -borland-pascal - disable GPC extensions, Previous:Mem; Port; Ptr; Seg; Ofs; PrefixSeg; etc., Up:BP Incompatibilities
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.