LP64 | ILP32

Category

Object code control

Pragma equivalent

None.

Purpose

Selects either AMODE 64 or AMODE 31 mode.

When the LP64 compiler option is in effect, the compiler generates AMODE 64 code using the z/Architecture® 64-bit instructions.

When the ILP32 compiler option is in effect, the compiler generates AMODE 31 code. This is the default and is the same mode as in previous releases of the compiler.

Note: AMODE is the addressing mode of the program code generated by the compiler. In AMODE 64 and AMODE 31, 64 and 31 refer to the range of addresses that can be accessed (in other words 64-bits and 31-bits are used to form the address respectively). When there is no ambiguity, we will refer to these as 64-bit mode and 31-bit mode. Refer to the information that follows for further information on the data model.

Syntax

Read syntax diagramSkip visual syntax diagram
   .-ILP32-.   
>>-+-LP64--+---------------------------------------------------><

Defaults

ILP32

Usage

LP64 and ILP32 are mutually exclusive. If they are specified multiple times, the compiler will take the last one.

LP64 and ILP32 refer to the data model used by the language. "I" is an abbreviation that represents int type, "L" represents long type, and "P" represents the pointer type. 64 and 32 refer to the size of the data types. When the ILP32 option is used, int, long and pointers are 32-bit in size. When LP64 is used, long and pointer are 64-bit in size; int remains 32-bit. The addressing mode used by LP64 is AMODE 64, and by ILP32 is AMODE 31. In the latter case, only 31 bits within the pointer are taken to form the address. For the sake of conciseness, the terms 31-bit mode and ILP32, will be used interchangeably in this document when there is no ambiguity. The same applies to 64-bit mode and LP64.

The LP64 option requires the XPLINK and GOFF compiler options. It also requires architecture level 5 or above (ARCH(5) or higher). ARCH(5), XPLINK, and GOFF are the default settings for LP64 if you don't explicitly override them. If you explicitly specify NOXPLINK, or NOGOFF, or specify an architecture level lower than 5, the compiler will issue a warning message, ignore NOXPLINK or NOGOFF, and raise the architecture level to 5.

Notes:
  1. The maximum size of a GOFF object is 1 gigabyte.
  2. ARCH(5) specifies the 2064 hardware models.

The prelinker cannot be used with 64-bit object modules.

Note: The Language Environment® element does not support mixing 64-bit and 31-bit object files in the same application. If one compilation unit is compiled with LP64, all compilation units within the program must be compiled with LP64. The binder will issue a message if it encounters mixed addressing modes during external name resolution.

In 31-bit mode, the size of long and pointers is 4 bytes and the size of wchar_t is 2 bytes. Under LP64, the size of long and pointer is 8 bytes and the size of wchar_t is 4 bytes. The size of other intrinsic datatypes remain the same between 31-bit mode and LP64. Under LP64, the type definition for size_t changes to long, and the type definition for ptrdiff_t changes to unsigned long. The following tables give the size of the intrinsic types:

Table 1. Size of intrinsic types in 64–bit mode
Type Size (in bits)
char, unsigned char, signed char 8
short, short int, unsigned short, unsigned short int, signed short, signed short int 16
int, unsigned int, signed int 32
long, long int, unsigned long, unsigned long int, signed long, signed long int 64
long long, long long int, unsigned long long, unsigned long long int, signed long long, signed long long int 64
pointer 64
Table 2. Size of intrinsic types in 31–bit mode
Type Size (in bits)
char, unsigned char, signed char 8
short, short int, unsigned short, unsigned short int, signed short, signed short int 16
int, unsigned int, signed int 32
long, long int, unsigned long, unsigned long int, signed long, signed long int 32
long long, long long int, unsigned long long, unsigned long long int, signed long long, signed long long int 64
pointer 32

The __ptr32 pointer qualifier is intended to make the process of porting applications from ILP32 to LP64 easier. Use this qualifier in structure members to minimize the changes in the overall size of structures. Note that these pointers cannot refer to objects above the 31-bit address line (also known as "the bar"). In general, the program has no control over the address of a variable; the address is assigned by the implementation. It is up to the programmer to make sure that the use of __ptr32 is appropriate within the context of the program's logic. For more information on the __ptr32 pointer qualifer, refer to z/OS XL C/C++ Language Reference.

Notes:
  1. The long and wchar_t data types also change in size.
  2. LP64 only supports OBJECTMODEL(IBM).

IPA effects

The IPA compile step generates information for the IPA link step for ILP32. The LP64 option affects the regular object module if you request one by specifying the IPA(OBJECT) option, in which case, the object module generated will be in 64-bit.

The IPA link step accepts the LP64 option, but ignores it. The DLL side deck generated by the binder has been enhanced. The side deck contains attribute flags to mark symbols exported from 64-bit DLLs; the flags are CODE64 and DATA64 for code and data respectively. IPA recognizes these flags.

The IPA link step will check that all objects have a consistent data model, either ILP32 or LP64. It checks both IPA object modules and non-IPA object modules. If the IPA link step finds a mixture of addressing modes among the object files, the compiler issues a diagnostic message and ends the compilation.

Predefined macros

Macros __64BIT__, _LP64, and __LP64__ are defined to 1 when the LP64 compiler option is in effect; otherwise, the macro _ILP32 is predefined to 1.