Go to main content

Oracle® Solaris 64-bit Developer's Guide

Exit Print View

Updated: November 2020
 
 

Changes in Derived Types

The current 32-bit compilation environment is identical to legacy Oracle Solaris OS releases with respect to derived types and their sizes. In the 64-bit compilation environment, some changes in derived types are necessary. These changed derived types are highlighted in the tables that follow.

Note that although the 32-bit and 64-bit compilation environments differ, the same set of headers is used for both, with the appropriate definitions determined by the compilation options. To understand the options available to an application developer, consider the _ILP32 and _LP64 feature test macros:

_ILP32 feature test macro

Specifies the ILP32 data model where int, long and pointers are 32-bit values. By itself, the use of this macro makes visible those derived types and sizes identical to historical Oracle Solaris implementations. This is the default compilation environment when building 32-bit applications. It ensures complete binary and source compatibility for both C and C++ applications.

_LP64 feature test macro

Specifies the _LP64 data model where int are 32-bit values and long and pointers are 64-bit values. _LP64 is defined by default when compiling in 64-bit mode. Other than making sure that either sys/types.h or sys/feature_tests.h is included in source in order to make visible the _LP64 definition, the developer needs to do nothing else.


Note -  The default compilation mode depends on the compiler being used. To determine whether your compiler produces 64-bit or 32-bit code by default, refer to the compiler documentation.

The following examples illustrate the use of feature test macros so that the correct definitions are visible, depending on the compilation environment.

Example 2  size_t Definition in _LP64
#if defined(_LP64)
typedef ulong_t size_t;   /* size of something in bytes */
#else
typedef uint_t size_t;    /* (historical version) */
#endif

When building a 64-bit application with the definition in this example, size_t is a ulong_t, or unsigned long, which is a 64-bit value in the LP64 model. In contrast, when building an 32-bit application, size_t is defined as a uint_t, or unsigned int, a 32-bit value in either in the ILP32 or the LP64 models.

Example 3  uid_t Definition in _LP64
#if defined(_LP64)
typedef int     uid_t;          /* UID type             */
#else
typedef long    uid_t;          /* (historical version) */
#endif

In the preceding examples, the same result would have been obtained had the ILP32 type representation been identical to the LP64 type representation. For example, if in the 32-bit application environment, size_t was changed to an ulong_t, or uid_t was changed to an int, these would still represent 32-bit quantities. However, retaining the historical type representation ensures consistency within 32-bit C and C++ applications, as well as complete binary and source compatibility with prior releases of the Oracle Solaris operating environment.

Figure 5, Table 5, General Differences Between Derived Types lists the derived types that have changed. When building a 32-bit application, the derived types available to the developer match those in the _ILP32 column. When building a 64-bit application, the derived types match those listed in the _LP64 column. All of these types are defined in sys/types.h, with the exception of the wchar_t and wint_t types, which are defined in wchar.h.

When reviewing these tables, remember that in the 32-bit environment, int, long, and pointers are 32-bit quantities. In the 64-bit environment, int are 32-bit quantities while long and pointers are 64-bit quantities.

Table 5  General Differences Between Derived Types
Derived Types
_ILP32
_LP64
blkcnt_t
longlong_t
long
id_t
long
int
major_t
ulong_t
uint_t
minor_t
ulong_t
uint_t
mode_t
ulong_t
uint_t
nlink_t
ulong_t
uint_t
paddr_t
ulong_t
not defined
pid_t
long
int
ptrdiff_t
int
long
size_t
uint_t
ulong_t
ssize_t
int
long
uid_t
long
int
wchar_t
long
int
wint_t
long
int

Figure 6, Table 6, Differences Between Derived Types Specific to Large Files lists the derived types specific to the Large Files compilation environment. These types are only defined if the feature test macro _LARGEFILE64_SOURCE is defined.

Table 6  Differences Between Derived Types Specific to Large Files
Derived Types
_ILP32
_LP64
blkcnt64_t
longlong_t
blkcnt_t
fsblkcnt64_t
u_longlong_t
blkcnt_t
fsfilcnt64_t
u_longlong_t
fsfilcnt_t
ino64_t
u_longlong_t
ino_t
off64_t
longlong_t
off_t

Figure 7, Table 7, Changed Derived Types – FILE_OFFSET_BITS Value lists the changed derived types with respect to the value of _FILE_OFFSET_BITS. You cannot compile an application with both _LP64 defined and _FILE_OFFSET_BITS==32. By default, if _LP64 is defined, _FILE_OFFSET_BITS==64. If _ILP32 is defined, and _FILE_OFFSET_BITS is not defined, then by default, _FILE_OFFSET_BITS==32. These rules are defined in the sys/feature_tests.h header file.

Table 7  Changed Derived Types – FILE_OFFSET_BITS Value
Derived Types
_ILP32 _FILE_ OFFSET_BITS ==32
_ILP32 _FILE_ OFFSET_BITS ==64
_LP64 _FILE_ OFFSET_BITS==64
ino_t
ulong_t
u_longlong_t
ulong_t
blkcnt_t
long
longlong_t
long
fsblkcnt_t
ulong_t
u_longlong_t
ulong_t
fsfilcnt_t
ulong_t
u_longlong_t
ulong_t
off_t
long
longlong_t
long