Is it required that either all or none of the C fixed-width integer types to be defined?

188 Views Asked by At

The specification specifies the types int8_t int16_t int32_t and int64_t (and their unsigned variants) and follows them with:

These types are optional.

In C the type char is at least 8 bits and short and int are at least 16 bits and long is at least 32 bits and long long is at least 64 bits. If they are all at least a certain width and at least as big as the smallest one, there could very well be for example an 8-bit type and a 32-bit type but no 16-bit type while satisfying those rules. As such could be 'gaps' in the fixed-width types?

By 'These types' do they mean each one individually or all of them as a whole? Could a conforming implementation define some but not all of the fixed width types? Do I have to worried about for example uint8_t being defined but not uint16_t?

3

There are 3 best solutions below

2
chux - Reinstate Monica On BEST ANSWER

Is it required that either all or none of the C fixed-width integer types to be defined?

No. An implementation may have CHAR_BIT == 16 and so only defined (u)int64_t, (u)int32_t and (u)int16_t, yet not (u)int8_t.


Do I have to worried about for example uint8_t being defined but not uint16_t?

Don't worry about such unicorns.

6
Carlo Arenas On

Assuming you are using C99 or newer and including <stdint.h> then you should expect to be able to figure out which of the types are available using the corresponding macro: INTn_MAX, INTn_MIN and UINTn_MAX (where n is 8, 16, 32 or 64).

8
Lundin On

stdint.h is a mandatory header for all compilers to implement, including freestanding implementations (embedded systems compilers). The C standard sorts the fixed width types into 3 categories:

  • Exact width types such as int32_t. If the compiler/system supports any of the 8, 16, 32 or 64 bit types with 2's complement and no padding bits, these types are mandatory.

    Otherwise, in case the compiler/system is wildly exotic, these types are optional - that is the text you quote but now placed in the correct context. ISO C17 says (7.20.1), emphasis mine:

    These types are optional. However, if an implementation provides integer types with widths of 8, 16, 32, or 64 bits, no padding bits, and (for the signed types) that have a two’s complement representation, it shall define the corresponding typedef names.

  • Minimum width types such as int_least32_t. These are mandatory to implement for all compilers.

  • Fastest minimum-width types such as int_fast32_t. These are mandatory to implement for all compilers.


As such could be 'gaps' in the fixed-width types?

Yeah in theory. Some exotic systems with 16 bit bytes exist (various more or less dysfunctional DSPs from TI) - these do not support int8_t so there is a "gap" there if you will. Some systems supporting 24 bit types also exist. As do 4 bit tiny microcontrollers.


By 'These types' do they mean each one individually or all of them as a whole?

Individually, as seen in the quote above. 8, 16, 32, or 64 bits.


Do I have to worried about for example uint8_t being defined but not uint16_t?

You don't need to worry about these types not being supported at all. Lack of portability to exotic/fictional/dysfunctional DSP systems is a feature not a problem. It is a huge waste of time to worry about portability to such systems. Anyone who decides to 1) use such an exotic DSP in the first place 2) decide to write C for it instead of asm which is the convention for DSPs only have themselves to blame. They can port your code, it's their problem created by them, not your problem.

If you are feeling paranoid you could add:

#include <stdio.h>
#if !defined(INT8_MIN) && (__STDC_VERSION__ <= 201710L)
  #error Your computer is too bad for this library.
#endif

NOTE: The upcoming C23 standard will finally drop support for exotic and fictional systems. All integers must use 2's complement, including all of the 3 categories above. (Source: C23 draft n3096, 7.22.1.)