The New Data Types

There are three classes of new data types: fixed-precision integer types, pointer-precision integer types, and specific-precision pointer types. These types were added to the Windows environment (specifically, to Basetsd.h) to allow developers to prepare for 64-bit Windows well before its introduction. These new types were derived from the basic C-language integer and long types, so they work in existing code. Therefore, use these data types in your code now, test your code on 32-bit Windows, and use the 64-bit compiler to find and fix portability problems in advance, so your driver can be ready when 64-bit Windows is available for testing.

In addition, adopting these new data types will make your code more robust. To use these data types, you must scan your code for potentially unsafe pointer usage, polymorphism, and data definitions. To be safe, use the new types. For example, when a variable is of type ULONG_PTR, it is clear that it will be used for casting pointers for arithmetic operations or polymorphism. It is not possible to indicate such usage directly by using the native Win32 data types. You can do this by using derived type naming or Hungarian notation, but both techniques are prone to errors.

Fixed-Precision Integer Types

Fixed-precision data types are the same length for 32-bit and 64-bit programming. To help you remember this, their precision is part of the name of the data type. The following are the fixed-precision data types.

Type Definition

DWORD32

32-bit unsigned integer

DWORD64

64-bit unsigned integer

INT32

32-bit signed integer

INT64

64-bit signed integer

LONG32

32-bit signed integer

LONG64

64-bit signed integer

UINT32

Unsigned INT32

UINT64

Unsigned INT64

ULONG32

Unsigned LONG32

ULONG64

Unsigned LONG64

Pointer-Precision Integer Types

As the pointer precision changes (that is, as it becomes 32 bits when compiled for 32-bit platforms, 64 bits when compiled for 64-bit platforms), these data types reflect the precision accordingly. Therefore, it is safe to cast a pointer to one of these types when performing pointer arithmetic; if the pointer precision is 64 bits, the type is 64 bits. The count types also reflect the maximum size to which a pointer can refer. The following are the pointer-precision and count types.

Type Definition

DWORD_PTR

Unsigned long type for pointer precision.

HALF_PTR

Signed integral type for half-pointer precision (16 bits on 32-bit systems, 32 bits on 64-bit systems).

INT_PTR

Signed integral type for pointer precision.

LONG_PTR

Signed long type for pointer precision.

SIZE_T

The maximum number of bytes to which a pointer can refer. Use this type for a count that must span the full range of a pointer.

SSIZE_T

Signed SIZE_T.

UHALF_PTR

Unsigned HALF_PTR.

UINT_PTR

Unsigned INT_PTR.

ULONG_PTR

Unsigned LONG_PTR.

Fixed-Precision Pointer Types

There are also new pointer types that explicitly size the pointer. Be cautious when using these pointer types in 64-bit code: If you declare the pointer using a 32-bit type, the system creates the pointer by truncating a 64-bit pointer.

Type Definition

POINTER_32

A 32-bit pointer. On a 32-bit system, this is a native pointer. On a 64-bit system, this is a truncated 64-bit pointer.

POINTER_64

A 64-bit pointer. On a 64-bit system, this is a native pointer. On a 32-bit system, this is a sign-extended 32-bit pointer.

Note that it is not safe to assume the state of the high pointer bit.

Helper Functions

The following inline functions (defined in Basetsd.h) can help you safely convert values from one type to another:

unsigned long HandleToUlong( const void *h )
long HandleToLong( const void *h )
void * LongToHandle( const long h )
unsigned long PtrToUlong( const void *p )
unsigned int PtrToUint( const void *p )
unsigned short PtrToUshort( const void *p )
long PtrToLong( const void *p )
int PtrToInt( const void *p )
short PtrToShort( const void *p )
void * IntToPtr( const int i )
void * UIntToPtr( const unsigned int ui )
void * LongToPtr( const long l )
void * ULongToPtr( const unsigned long ul )

Warning  IntToPtr sign-extends the int value, UIntToPtr zero-extends the unsigned int value, LongToPtr sign-extends the long value, and ULongToPtr zero-extends the unsigned long value.