Examples of structure alignment differences under ILP32 and LP64

This section provides examples of three structures that illustrate the impact of the ILP32 and LP64 programming environments on structure size and alignment.

In accordance with the z/OS rule of alignment (see z/OS basic rule of alignment), the length of each data member produced by the source code depends on the runtime environment, as shown in Table 1.

Table 1. Comparison of data structure member lengths produced from the same code
Source:
#include <stdio.h>

int main(void) {
    struct li{
             long la;
             int ia;
             } li;
    struct lii{
              long la;
              int ia;
              int ib;
              } lii;
    struct ili{
              int ia;
              long la;
              int ib;
              } ili;
    printf("length li = %d\n",sizeof(li));
    printf("length lii = %d\n",sizeof(lii));
    printf("length ili = %d\n",sizeof(ili));
}
ILP32 member lengths:
length li = 8    1 
length lii = 12  3 
length ili = 12  3 
LP64 member lengths:
length li = 16   2 
length lii = 16  3 
length ili = 24  3 
Notes:
  1. In a 32-bit environment, both int and long int have 4-byte alignments, so each of these members is aligned on 4-byte boundary. In accordance with the z/OS rule of alignment, the structure as a whole has a 4-byte alignment. The size of struct li is 8 bytes. See Figure 1.
  2. In a 64-bit environment, int has a 4-byte alignment and long int has an 8-byte alignment. In accordance with the z/OS rule of alignment, the structure as a whole has an 8-byte alignment. See Figure 1.
  3. The struct lii and the struct ili have the same members, but in a different member order. See Figure 2 and Figure 3. Because of the padding differences in each environment:
    • Under ILP32:
      • The size of struct lii is 12 bytes (4-byte long + 4-byte int + 4-byte int)
      • The size of struct ili is 12 bytes (4-byte int + 4-byte long + 4-byte int)
    • Under LP64:
      • The size of struct lii is 16 bytes (8-byte long + 4-byte int + 4-byte int)
      • The size of struct ili is 24 bytes (4-byte int + 4-byte pad + 8-byte long + 4-byte int + 4-byte pad)

The ILP32 and LP64 alignments for the structs defined by the code shown in Table 1 are compared in Figure 1, Figure 2, and Figure 3.

Figure 1 compares how struct li is aligned under ILP32 and LP64. The structure has two members: Under ILP32, each member is 4 bytes long and is aligned on a 4-byte boundary, making the structure 8 bytes long. Under LP64, member la is 8 bytes long and is aligned on an 8-byte boundary. Member ia is 4 bytes long, so the compiler inserts 4 padding bytes to ensure that the structure is aligned to the strictest alignment requirement for its largest member. Then, the structure can be used as part of an array under LP64.
Figure 1. Comparison of struct li, alignments under ILP32 and LP64
This figure compares how struct li is aligned under ILP32 and LP64,

Figure 2 and Figure 3 show structures that have the same members, but in a different order. Compare these figures to see how the order of the members impacts the size of the structures in each environment.

Figure 2 compares how struct lii is aligned under ILP32 versus LP64. struct lii has three members: Under ILP32, each member is 4 bytes long and is aligned on a 4-byte boundary, making the structure 12 bytes long. Under LP64, member la is 8 bytes long and is aligned on an 8-byte boundary. Member ia and member ib are each 4 bytes long, so the structure is 16 bytes long and can align on an 8-byte boundary without padding.
Figure 2. Comparison of struct lii alignments under ILP32 and LP64
This figure compares how struct lii is aligned under ILP32 and LP64.
Figure 3 compares how struct ili is aligned under ILP32 and LP64. struct ili has three members:

Under ILP32, each member is 4 bytes long and is aligned on a 4-byte boundary, making the structure 12 bytes long. Under LP64, the compiler inserts padding after both member ia and member ib, so that each member with padding is 8 bytes long (member la is already 8 bytes long) and are aligned on 8-byte boundaries. The structure is 24 bytes long.

Figure 3. Comparison of struct ili alignments under ILP32 and LP64
This figure compares how struct ili is aligned under ILP32 and LP64.