Jump to content United States-English
HP.com Home Products and Services Support and Drivers Solutions How to Buy
» Contact HP
More options
HP.com home
HP-UX 64-bit Porting and Transition Guide: HP 9000 Computers > Chapter 5 Writing Portable Code

Using Integral Types Defined in <inttypes.h>

» 

Technical documentation

Complete book in PDF
» Feedback
Content starts here

 » Table of Contents

 » Glossary

 » Index

The <inttypes.h> header files provide the following features that help you write portable code:

  • integral type definitions

  • macros for constants

  • macros for printf()/scanf() specifiers

When you use <inttypes.h>, you can maintain one set of source files for both data models. Using the typedefs and constants included in these header files protects your code from underlying data model changes. It also reduces the need to #ifdef platform-specific code, which improves the readability of your source code.

There are two <inttypes.h> header files. The following information is included in <sys/_inttypes.h>:

  • basic integral data types for 8, 16, 32, and 64 bits

  • macros that can create constants of a specific size and sign

The following information is included in <inttypes.h>:

  • data types for pointers

  • data types for the most efficient integer types

  • data types for the largest integer types

  • data types for the smallest integral types of at least 8, 16, 32, and 64 bits

Integer Data Types with Consistent Lengths

The basic types in <sys/_inttypes.h> have consistent lengths on UNIX 32-bit and 64-bit platforms. Use these basic data types instead of the standard C language types whenever you want data types to remain the same size across different architectures.

Table 5-1 “C Basic Integer Types in <sys/_inttypes.h>” shows the basic integral types in <sys/_inttypes.h>:

Table 5-1 C Basic Integer Types in <sys/_inttypes.h>

Type Definition Name

Description

int8_t

8-bit signed integer

uint8_t

8-bit unsigned integer

int16_t

16-bit signed integer

uint16_t

16-bit unsigned integer

int32_t

32-bit signed integer

uint32_t

32-bit unsigned integer

int64_t

64-bit signed integer

uint64_t

64-bit unsigned integer

 

The pointer data types are signed and unsigned integer data types that are large enough to hold a pointer. A pointer can be moved to or from these data types without corruption.

Table 5-2 Pointer Types in <inttypes.h>

Type Definition Name

32-bit Mode

64-bit Mode

intptr_t

32-bit signed integer

64-bit signed integer

uintptr_t

32-bit unsigned integer

64-bit unsigned integer

 

Using Integer Data Types with Consistent Lengths

One way to improve portability of programs that require integral data items to be 32-bits or 64-bits long, regardless of the hardware platform, is to #include the <inttypes.h> header file, and to make the following substitutions:

Table 5-3 Title not available (Using Integer Data Types with Consistent Lengths )

Instead of

Use

short

int16_t

unsigned short

uint16_t

int

int32_t

unsigned int

uint32_t

long

int32_t or int64_t

unsigned long

uint32_t or unint64_t

long long

int64_t

unsigned long long

uint64_t

 

Excerpts from <sys/_inttypes.h>

Here are some typedefs in <sys/_inttypes.h> that conform to the XPG5 standard:

typedef int int32_t;      /* 32-bit signed integral type   */
typedef int64_t intmax_t; /* largest signed integral type */
typedef unsigned long uint64_t; /* 64-bit unsigned integral type */

Here are some HP extensions:

#define INT32_C(_c)     /* Create a 32-bit signed constant     */
#define UINT32_C(_c) /* Create a 32-bit unsigned constant */

#define UINT64_MAX /* If this macro tests false, the unsigned
64-bit data type is not supported on
the platform. */

#define PRId64 /* printf specifier for a 64-bit integral value */
#define SCNd64 /* scanf specifier for a 64-bit integral value */

Examples Using Consistent Length Data Types and Macros

The following code uses constructs that are not 64-bit clean:

Before:

#include <limits.h>
#include <stdio.h>
. . .
long value;
long mask = 1L << ((sizeof(long) * CHAR_BIT)-1);
scanf("%ld", &value);
if (value = 0x7fffffff) /* Test for max 32-bit value. */
printf("Number is %ld\n", value);
if (mask & value) /* Handle bad value. */
. . .

The after code has been made 64-bit clean by using <inttypes.h>:

After:

#include <limits.h>
#include <stdio.h>
#include <inttypes.h>
. . .
int32_t value;
int32_t mask = INT32_C(1)<<((sizeof(int32_t) * CHAR_BIT)-1);
scanf("%" SCNd32, &value);
if (value = INT32_MAX) /* Test for max 32-bit value.*/
printf("Maximum 32-bit signed integer is \
%" PRId32 "\n", value);
if (mask & value) /* Handle bad value. */
. . .

Example 2: Formatted I/O using printf(3S)

Use the PRIxn constants defined in <inttypes.h> to select the correct printf() formatting option for the data types defined in <inttypes.h>. For example:

Before:

long result_value;
printf ("Result = %lx\n", result_value);

After:

#include <inttypes.h>
int32_t result_value;
printf ("Result = %" PRIx32 "\n", result_value);

The before code prints a 32-bit number on 32-bit platforms and a 64-bit number on a 64-bit platform. The after code prints a 32-bit number, regardless of the platform. The macro PRIx32 from <inttypes.h> is used instead of the literal lx. PRIx32 is then defined as the appropriate formatting symbol.

intfast Data Types with Defined Minimum Sizes

When execution speed of programs is important, use the intfastx_t data types in <inttypes.h>. You select data types based on the minimum integer size required by your application. The <inttypes.h> header file then maps the intfast data types to the fastest appropriate data type for the target hardware platform. These data types include:

intfast_t

fastest signed integral data type of at least 16-bits

intfast8_t

fastest signed integral data type at least 8-bits long

uintfast8_t

fastest unsigned integral data type at least 8-bits long

intfast16_t

fastest signed integral data type at least 16-bits long

uintfast16_t

fastest unsigned integral data type at least 16-bits long

intfast32_t

fastest signed integral data type at least 32-bits long

uintfast32_t

fastest unsigned integral data type at least 32-bits long

Example Using intfastn_t Data Types

Suppose you need a loop to execute as fast as possible on a target platform. You could change the following:

Before:

int i, j;
j = 0;
for (i = 1; i<=127; i++)
{
j = j+i;
}

to use the most efficient and portable integer data types as follows:

After:

intfast8_t i;
intfast16_t j = 0;
for (i =1; i<=INT8_MAX; i++)
{
j = j+i;
}
Printable version
Privacy statement Using this site means you accept its terms Feedback to webmaster
© 1998 Hewlett-Packard Development Company, L.P.