Individual members of a union are mapped the same way as members of the structure. That is, each of the members, if not a union, is mapped as if it were a member of a structure. This means that the first storage locations for each of the members of a union do not overlay each other if each of the members requires different alignment and therefore different padding before the beginning of the member.
Consider the following union:
dcl
1 A union,
2 B,
3 C char(1),
3 D fixed bin(31),
2 E,
3 F char(2),
3 G fixed bin(31);
Three bytes of padding are added between A and B. Two bytes are added between A and E.
In order to ensure that the first storage location of each of the members of a union is the same, make sure that the first member of each has the same alignment requirement and it is the same as the highest alignment of any of its members (or its member’s members).
The remainder of the discussion applies to members of a structure or union, which can be minor structures or elementary variables.
For any major or minor structure, the length, alignment requirement, and position relative to an 8-byte boundary depend on the lengths, alignment requirements, and relative positions of its members. The process of determining these requirements for each level and for the complete structure is known as structure mapping.
You can use structure mapping for determining the record length required for a structure when record-oriented input/output is used, and determining the amount of padding or rearrangement required for correct alignment of a structure for locate-mode input/output.
The structure mapping process minimizes the amount of unused storage (padding) between members of the structure. It completes the entire process before the structure is allocated, according (in effect) to the rules discussed in the following paragraphs.
Structure mapping is not a physical process. Terms such as shifted and offset are used purely for ease of discussion, and do not imply actual movement in storage. When the structure is allocated, the relative locations are already known as a result of the mapping process.
The mapping for a complete structure reduces to successively combining pairs of items (elements, or minor structures whose individual mappings have already been determined). Once a pair has been combined, it becomes a unit to be paired with another unit, and so on until the complete structure is mapped. The rules for the process are categorized as follows:
These rules are described below, and an example shows an application of the rules in detail. It is necessary to understand the difference between the logical level and the level-number of structure elements. The logical levels are immediately apparent if the structure declaration is written with consistent level-numbers or suitable indentation (as in the detailed example given after the rules). In any case, you can determine the logical level of each item in the structure by applying the following rule to each item in turn, starting at the beginning of the structure declaration:
In the following example, the lower line shows the logical level for each item in the declaration.
dcl 1 A, 4 B, 5 C, 5 D, 3 E, 8 F, 7 G;
1 2 3 3 2 3 3
The steps in determining the order of pairing are as follows:
For purposes of this explanation, think of storage as contiguous doublewords, each having 8 bytes, numbered 0 through 7, which indicate the offset from a doubleword boundary. Think of the bytes as numbered continuously from 0 onward, starting at any byte, so that lengths and offsets from the start of the structure can be calculated.
After this process has been completed, any padding between the two elements has been minimized and does not change throughout the rest of the operation. The pair is now a unit of fixed length and alignment requirement; its length is the sum of the two lengths plus padding, and its alignment requirement is the higher of the two alignment requirements (if they differ).
The example of structure mapping given below shows the rules applied to a structure declared ALIGNED. Mapping of aligned structures is more complex because of the number of alignment requirements. The effect of the UNALIGNED attribute is to reduce to one byte the alignment requirements for halfwords, fullwords, and doublewords, and to reduce to one bit the alignment requirement for bit strings. The same structure mapping rules apply, but the reduced alignment requirements are used. The only unused storage will be bit padding within a byte when the structure contains bit strings.
AREA data cannot be unaligned.
If a structure has the UNALIGNED attribute and it contains an element that cannot be unaligned, UNALIGNED is ignored for that element. The element is aligned and an error message is produced. For example, in a program with the following declaration, C is given the attribute ALIGNED because the inherited attribute UNALIGNED conflicts with AREA.
declare 1 A unaligned,
2 B,
2 C area(100);
The following example shows the application of the structure mapping rules for a structure with the specified declaration.
declare 1 A aligned,
2 B fixed bin(31),
2 C,
3 D float decimal(14),
3 E,
4 F entry,
4 G,
5 H character(2),
5 I float decimal(13),
4 J fixed binary(31,0),
3 K character(2),
3 L fixed binary(20,0),
2 M,
3 N,
4 P fixed binary(15),
4 Q character(5),
4 R float decimal(2),
3 S,
4 T float decimal(15),
4 U bit(3),
4 V char(1),
3 W fixed bin(31),
2 X picture '$9V99';
The minor structure at the deepest logical level is G, so this is mapped first. Then E is mapped, followed by N, S, C, and M, in that order.
For each minor structure, a table in Figure 10 shows the steps in the process, and a diagram in Figure 11 shows a visual interpretation of the process. Finally, the major structure A is mapped as shown in Figure 17. At the end of the example, the structure map for A is set out in the form of a table (Figure 18) showing the offset of each member from the start of A.