| United States-English |
|
|
|
![]() |
HP-UX 64-bit Porting and Transition Guide: HP 9000 Computers > Chapter 3 HP-UX 64-bit Porting
Concepts ILP32 to LP64 Porting Concerns |
|
Some fundamental changes occur when moving from the ILP32 data model to the LP64 data model:
These differences can potentially impact porting in the following areas:
See Also: . See Chapter 4 “Transitioning C and aC++ Programs to 64-bit Mode ” to learn how to identify and fix 64-bit porting issues. Truncation problems can happen when assignments are made between 64-bit and 32-bit data items. Since ints, longs, and pointers are 32 bits in ILP32, mixed assignments between these data types do not present any special concerns. However, in the LP64 data model, longs and pointers are no longer the same size as ints. In LP64, truncation will occur when pointers or longs are assigned to ints. In LP64, truncation can occur during:
Pointers and longs are not the only data types whose size has changed. Some data types defined in header files that are 32 bits under ILP32 — for example, off_t — are now 64 bits. Variables declared with off_t may be truncated when assigned to ints in LP64. Avoiding pointer corruption is an important concern when migrating to LP64:
Pointer arithmetic is a source of difficulty in migration. Standard C behavior increments a pointer by the size of the data type to which it points. This means if the variable p is a pointer to long, then the operation (p + 1) increments the value of p by 4 bytes in ILP32 and by 8 bytes in LP64. Casts between long* to int* are problematic because the object of a long pointer is 64 bits in size, but the object of an int pointer is only 32 bits in size. When comparisons and arithmetic operations are performed between variables and constants with different data types, ANSI C first converts these types to compatible types. For example, when a short is compared to a long, the short is first converted to a long. This conversion process is called data type promotion. Certain data type promotions result in signed numbers being treated as unsigned numbers. When this happens, you can occasionally get unexpected results. For example:
In ANSI C under the 32-bit data model, the results are shown: The intermediate result (an unsigned int) and the final result (a signed long) have the same internal representation because they are both 32 bits. Since the final result is signed, the answer is -1. In ANSI C under the 64-bit data model, the results are different: When the 32-bit intermediate result (an unsigned int) is converted to the 64-bit final result (a signed long), the left 32 bits are zero-filled. This results in a very large 64-bit positive number. Data alignment rules determine where fields are located in memory. There are differences between the LP64 data alignment rules and the ILP32 data alignment rules. In ILP32, pointers and longs are 32 bits and are aligned on 32-bit boundaries. In LP64, pointers and longs are 64 bits and are aligned on 64-bit boundaries. Applications that do not consider alignment differences between ILP32 and LP64 can have trouble sharing binary data. Data exchanged between ILP32 and LP64 mode programs, whether via files, remote procedure calls, or other messaging protocols, may not be aligned as expected. Table 3-2 “ILP32 and LP64 Data Alignment ” shows the data alignment for C data types: Table 3-2 ILP32 and LP64 Data Alignment
Data alignment of structures is affected by porting from ILP32 to LP64. Structure members may be padded differently in ILP32 and LP64 in order for the structure members to begin on specific alignment boundaries. Here is an example structure that is aligned differently for ILP32 and LP64:
The tnode structure is aligned according to the alignment shown in Table 3-2 “ILP32 and LP64 Data Alignment ”. Figure 3-3 “ILP32 Alignment of struct tnode ” shows the alignment for tnode in ILP32: In ILP32, this data structure contains 20 bytes. Figure 3-4 “LP64 Alignment of struct tnode ” shows the alignment for the tnode structure in LP64. In LP64, this data structure contains 40 bytes. In the example shown, the same structure definition has different sizes and the structure members have different offsets. For More Information: . For information on how to create portable data structures, see the HP C Programmer's Guide or HP-UX Applications Interoperability White Paper, URL://www.software.hp.com/STK/. When a program with hexadecimal constants is ported from ILP32 to LP64, the data types assigned to the constants may change. The following table illustrates some common hex constants and their types:
In LP64, 32-bit hexadecimal constants may no longer set pointers or masks to the correct value. In LP64, the first 32 bits of 64-bit pointers contain significant information. Unqualified bit fields are unsigned by default in LP64. In ILP32, unqualified bit fields are signed by default. Bit fields of enumerated types are signed if the enumeration base type is signed and unsigned if the enumeration base type is unsigned. Unnamed, non-zero length bit fields do not affect the alignment of a structure or union in LP64. In ILP32, unnamed, non-zero length bit fields affect the alignment of structures and unions. Bit shifts and bit masks are sometimes coded with the assumption that the operations are performed in variables that have the same data type as the result. In cases such as: a = b operation c the data type used for the intermediate result of the operation depends on the types of b and c. The intermediate result is then promoted to the type of a. If the result requires 64 bits, but b and c are 32-bit data types, then the intermediate result either overflows or is truncated before being assigned to a. In the following example, the left operand 1 is a small numeric constant which the compiler treats as a 32-bit value in both ILP32 and LP64:
This bit shift uses a 32-bit data type as the intermediate result. In 64-bit mode, the operation overflows and the final result is undefined as shown: You can use suffixes such as L and UL for long and unsigned long if you need long constants. For example, in 64-bit mode, the above code fragment can be changed to:
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||