15.1.4 C Structure Layout
C compilers on different systems lay out structures differently. In
some cases there can even be layout differences between different C
compilers on the same system. Compilers add gaps between fields, and
these gaps have different sizes and are at different locations. You can
normally assume that there are no gaps between fields of type
char or array of
char. However, you can not make any
assumptions about gaps between fields of any larger type. You also can
not make any assumptions about the layout of bitfield types.
These structure layout issues mean that it is difficult to portably use
a C struct to define the format of data which may be read on another
type of system, such as data in a file or sent over a network
connection. Portable code must read and write such data field by field,
rather than trying to read an entire struct at once.
Here is an example of non-portable code when reading data which may have
been written to a file or a network connection on another type of
system. Don't do this.
/* Example of non-portable code; don't do this */
read (fd, &s, sizeof s);
Instead, do something like this (the struct
s is assumed to be
the same as above):
Naturally the code to write out the structure should be similar.
unsigned char buf;
read (fd, buf, sizeof buf); /* Should check return value */
s.i = buf | (buf << 8);
s.j = buf | (buf << 8) | (buf << 16) | (buf << 24);