The difference of int8_t, int_least8_t and int_fast8_t?
The difference is defined in the sections of the C99 standard that Carl Norum quoted. But it may be useful to have an example.
Suppose you have a C compiler for a 36-bit system, with char
= 9 bits, short
= 18 bits, int
= 36 bits, and long
= 72 bits. Then
-
int8_t
does not exist, because there is no way to satisfy the constraint of having exactly 8 value bits with no padding. -
int_least8_t
is a typedef ofchar
. NOT ofshort
orint
, because the standard requires the smallest type with at least 8 bits. -
int_fast8_t
can be anything. It's likely to be a typedef ofint
if the "native" size is considered to be "fast".
From the spec section 7.8.1.1 Exact-width integer types, paragraph 1:
The typedef name
int
N_t
designates a signed integer type with width N , no padding bits, and a two’s complement representation. Thus,int8_t
denotes a signed integer type with a width of exactly 8 bits.
And from: 7.18.1.2 Minimum-width integer types, paragraph 1:
The typedef name
int_least
N_t
designates a signed integer type with a width of at least N, such that no signed integer type with lesser size has at least the specified width. Thus,int_least32_t
denotes a signed integer type with a width of at least 32 bits.
And finally from 7.18.1.3 Fastest minimum-width integer types, paragraph 2:
The typedef name
int_fast
N_t
designates the fastest signed integer type with a width of at least N. The typedef nameuint_fast
N_t
designates the fastest unsigned integer type with a width of at least N.
Here's a conceptually simple answer: the width of int*N_t for all three types must be >= N. intN_t has exactly N bits, int_leastN_t is the least (narrowest) such type, and int_fastN_t is the fastest such type.
For example, on a machine with 8 bit bytes and 32 bit fast registers, int8_t and int_least8_t are aliased to signed char but int_fast8_t is aliased to int32_t. Whereas, if the implementation chose to define them, int_least24_t and int_fast24_t would both be aliased to int32_t, with int24_t left undefined.
Edit: as Technophile points out below, the real issue for fast types is memory, not registers (generally, operations on the low-order bits of registers can be done just as fast as on the whole register). For example, writing to an int8_t in memory may require loading the 32-bit word containing it, modifying just the byte, and then writing it back, whereas if it were stored in a 32-word it could be written without reading.