C Programming/C Reference/stdint.h

< C Programming < C Reference

stdint.h is a header file in the C standard library introduced in the C99 standard library section 7.18 to allow programmers to write more portable code by providing a set of typedefs that specify exact-width integer types, together with the defined minimum and maximum allowable values for each type, using macros[1] . This header is particularly useful for embedded programming which often involves considerable manipulation of hardware specific I/O registers requiring integer data of fixed widths, specific locations and exact alignments. stdint.h (for C or C++), and cstdint (for C++) can be downloaded or quickly created if they are not provided.

The naming convention for exact-width integer types is intN_t for signed int and uintN_t for unsigned int [1] . For example int8_t and uint64_t amongst others could be declared together with defining their corresponding ranges INT8_MIN to INT8_MAX and 0 (zero) to UINT64_MAX; again using a similar but upper case naming convention. In addition stdint.h defines limits of integer types capable of holding object pointers such as UINTPTR_MAX, the value of which depends on the processor and its address range[1].

The exact-width types and their corresponding ranges are only included in that header if they exist for that specific compiler/processor. Note that even on the same processor, two different compiler implementations can differ. The use of #if or #ifdef would allow the inclusion or exclusion of types by the use of compilers preprocessor so that the correct exact-width set is selected for a compiler and its processor target.

The related include file <limits.h> provides macros values for the range limits of common integer variable types. In C <limits.h> is already included in <stdint.h>, but in contrast to <stdint.h> which is implementation independent; all maximum and minimum integer values defined in <limits.h> are compiler implementation specific. For example a compiler generating 32 bit executables will define LONG_MIN as −2,147,483,648 [−231] however for 64 bit processors targets, LONG_MIN can be −9,223,372,036,854,775,808 [−263].

Background

Corresponding integer types

The C standard has a notion of "corresponding integer types". Informally, what this means is for any integer type T:

typedef   signed T A;
typedef unsigned T B;

the type A and the type B are said to be corresponding integer types (note: typedef doesn't create a new type, it creates a new identifier as a synonym for the given type). This is important for two reasons:

Both of these combined require code like:

A a = 1;
B b = 1;
*(B*)&a = 0;
*(A*)&b = 0;

to have defined behavior by the standard (as opposed to being undefined in the general case). There are many caveats to how far you can push this, so it's important to actually read the C standard to see what's legal or not (the bulk of this has to deal with padding bits and out of range representations).

Representation

The C99 standard elaborated the difference between value representations and object representations.

The object representation of an integer consists of 0 or more padding bits, 1 or more value bits[1], and either 0 or 1 sign bits (this doesn't count as a value bit) depending on the signedness of the integer type.

The value representation is a conceptual representation of an integer. The value representation ignores any padding bits and does a (possible) rearrangement to the bits so that the integer is ordered sequentially from most significant value bit to least significant value bit. Most programmers deal with this representation because it allows them easily to write portable code by only dealing with −0 and out of range values as opposed to both of those in addition to tricky aliasing rules and trap representations if they choose to deal with the object representation directly.

Signed representation

The C standard allows for only three signed integer representations specified by the compiler writer:

Integer types

The types <something>_t and u<something>_t are required to be corresponding signed and unsigned integer types. For the types that are marked optional, an implementation must either define both <something>_t and u<something>_t or neither of the two. The limits of these types shall be defined with macros with a similar name in the same fashion as described below.

If a type is of the form [u]<something>N_t (or similarly for a preprocessor define), N must be a positive decimal integer with no leading 0's.

Exact-width integer types

These are of the form intN_t and uintN_t. Both types must be represented by exactly N bits with no padding bits. intN_t must be encoded as a two's complement signed integer and uintN_t as an unsigned integer. These types are optional unless the implementation supports types with widths of 8, 16, 32 or 64, then it shall typedef them to the corresponding types with corresponding N. Any other N is optional[1] .

Specific integral type limits
Specifier Signing Bits Bytes Minimum Value Maximum Value
int8_t Signed 8 1 −27 which equals −128 27 − 1 which is equal to 127
uint8_t Unsigned 8 1 0 28 − 1 which equals 255
int16_t Signed 16 2 −215 which equals −32,768 215 − 1 which equals 32,767
uint16_t Unsigned 16 2 0 216 − 1 which equals 65,535
int32_t Signed 32 4 −231 which equals −2,147,483,648 231 − 1 which equals 2,147,483,647
uint32_t Unsigned 32 4 0 232 − 1 which equals 4,294,967,295
int64_t Signed 64 8 −263 which equals −9,223,372,036,854,775,808 263 − 1 which equals 9,223,372,036,854,775,807
uint64_t Unsigned 64 8 0 264 − 1 which equals 18,446,744,073,709,551,615

The limits of these types are defined with macros with the following formats:

Minimum-width integer types

These are of the form int_leastN_t and uint_leastN_t. int_leastN_t is a signed integer and uint_leastN_t is an unsigned integer[1] .

The standard mandates that these have widths greater than or equal to N, and that no smaller type with the same signedness has N or more bits. For example, if a system provided only a uint32_t and uint64_t, uint_least16_t must be equivalent to uint32_t.

An implementation is required to define these for the following N: 8, 16, 32, 64. Any other N is optional.

The limits of these types are defined with macros with the following formats:

stdint.h should also define macros which will convert constant decimal, octal or hexadecimal value which are guaranteed to be suitable for the corresponding types and to be usable with the #if:

Fastest minimum-width integer types

These are of the form int_fastN_t and uint_fastN_t.

The standard does not mandate anything about these types except that their widths must be greater than or equal to N. It also leaves it up to the implementor to decide what it means to be a "fast" integer type.

An implementation is required to define these for the following N: 8, 16, 32, 64[2].

The limits of these types are defined with macros with the following formats:

Integers wide enough to hold pointers

intptr_t and uintptr_t is a signed and unsigned integer which are guaranteed to hold the value of a pointer. These two types are optional.

The limits of these types are defined with the following macros:

Greatest-width integer types

intmax_t and uintmax_t is a signed and unsigned integer which are of the greatest supported width. They are, in other words, the integer types which have the greatest limits.

The limits of these types are defined with macros with the following formats:

Macros which will convert constant decimal, octal or hexadecimal value which will suit the corresponding type are also defined:

Other integer limits

Criticisms and caveats

See also

Notes and references

  1. 1 2 3 4 5 6 7 8 technically, it actually allows 0 or more value bits, but the only way you can construct this is with a single-bit bit-field of a signed integer
  2. http://www.tuxgraphics.org/common/src2/article09043/avr-libc-user-manual-1.6.4/group__avr__stdint.html
  3. http://linux.die.net/man/3/intptr_t

As stdint.h is not shipped with older C++ compilers and Visual Studio C++ products prior to Visual Studio 2010, third-party implementations are available:

This article is issued from Wikibooks. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.