Defining pad members to avoid data alignment problems

If you want to allow the structure to be shared, you might be able to reorder the fields in the data structure to get the alignments in both 32-bit and 64-bit environments to match (as shown in Table 1), depending on the data types used in the structure and the way in which the structure as a whole is used (for example, whether the structure is used as a member of another structure or as an array).

If you are unable to reorder the members of a structure, or if reordering alone cannot provide correct alignment, you can define paddings that force the members of the structure to fall on their natural boundaries regardless of whether it is compiled under ILP32 or LP64. A conditional compilation section is required whenever a structure uses data types that have different sizes in 32-bit and 64-bit environments.

The example in Table 1 shows how the source code in Table 1 can be modified to avoid the data alignment problem.

Table 1. Example of source code that successfully shares pointers between ILP32 and LP64 programs
Source:
struct T {
    char c;
    short s;
    #if !defined(_LP64)
        char pad1[4];
    #endif
    int *p;
    #if !defined(_LP64)
        char pad2[4];
    #endif
} t;
ILP32/ LP64 size and member layout:
sizeof(t) = 16
offsetof(t, c) = 0 sizeof(c) = 1
offsetof(t, s) = 2 sizeof(s) = 2
offsetof(t, p) = 8 sizeof(p) = 4

Figure 1 shows the member layout of the structure with user-defined padding. Because the pointer is a different size in each environment, it is aligned on different a boundary in each environment. This means that if the code is compiled under both ILP32 and LP64, there are likely to be alignment problems. This figure illustrates the solution, which is to define pad members of type character that prevent the possibility of data misalignment.

Note: When inserting paddings into structures, use an array of characters. The natural alignment of a character is 1-byte, which means that it can reside anywhere in memory.
Figure 1. Example of user-defined data padding for a structure that is shared or exchanged among 32-bit and 64-bit processes.
Figure illustrates how the compiler treats the same source code under ILP32 and LP64.