stdatomic.h
appears to contain atomic_uint_least16_t
and atomic_uint_fast16_t
, which are _Atomic
versions of the stdint.h
types uint_least16_t
and uint_fast16_t
, but it does not contain atomic_uint16_t
. Why?
For some background information from the N1548 draft:
7.18.1.1 Exact-width integer types
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 such a signed integer type with a width of exactly 8 bits.2 The typedef name
uint
N_t
designates an unsigned integer type with width N and no padding bits. Thus,uint24_t
denotes such an unsigned integer type with a width of exactly 24 bits.3 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.
7.18.1.2 Minimum-width integer types
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.2 The typedef name
uint_least
N_t
designates an unsigned integer type with a width of at least N, such that no unsigned integer type with lesser size has at least the specified width. Thus,uint_least16_t
denotes an unsigned integer type with a width of at least 16 bits.3 The following types are required:
int_least8_t int_least16_t int_least32_t int_least64_t uint_least8_t uint_least16_t uint_least32_t uint_least64_t
All other types of this form are optional.
(and so on, to include the int_fast
N_t
/ uint_fast
N_t
types, etc.)
It is worth highlighting in paragraph 3:
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.
This means that if, for example, I have a type like int
or short
which is implemented as a 16-bit integer with two's complement representation, then the implementation shall define int16_t
.
The atomic_
types for <stdatomic.h>
are also listed in N1548 (reproduced below) but it does not make a corresponding requirement that if the implementation has a int16_t
then there is a atomic_int16_t
--- that is the nature of my question.
7.17.6 Atomic integer and address types
1 For each line in the following table, the atomic type name is declared as the corresponding direct type.
Atomic type name Direct type ---------------- ----------- atomic_char _Atomic char atomic_schar _Atomic signed char atomic_uchar _Atomic unsigned char atomic_short _Atomic short atomic_ushort _Atomic unsigned short atomic_int _Atomic int atomic_uint _Atomic unsigned int atomic_long _Atomic long atomic_ulong _Atomic unsigned long atomic_llong _Atomic long long atomic_ullong _Atomic unsigned long long atomic_char16_t _Atomic char16_t atomic_char32_t _Atomic char32_t atomic_wchar_t _Atomic wchar_t atomic_int_least8_t _Atomic int_least8_t atomic_uint_least8_t _Atomic uint_least8_t atomic_int_least16_t _Atomic int_least16_t atomic_uint_least16_t _Atomic uint_least16_t atomic_int_least32_t _Atomic int_least32_t atomic_uint_least32_t _Atomic uint_least32_t atomic_int_least64_t _Atomic int_least64_t atomic_uint_least64_t _Atomic uint_least64_t atomic_int_fast8_t _Atomic int_fast8_t atomic_uint_fast8_t _Atomic uint_fast8_t atomic_int_fast16_t _Atomic int_fast16_t atomic_uint_fast16_t _Atomic uint_fast16_t atomic_int_fast32_t _Atomic int_fast32_t atomic_uint_fast32_t _Atomic uint_fast32_t atomic_int_fast64_t _Atomic int_fast64_t atomic_uint_fast64_t _Atomic uint_fast64_t atomic_intptr_t _Atomic intptr_t atomic_uintptr_t _Atomic uintptr_t atomic_size_t _Atomic size_t atomic_ptrdiff_t _Atomic ptrdiff_t atomic_intmax_t _Atomic intmax_t atomic_uintmax_t _Atomic uintmax_t
2 The semantics of the operations on these types are defined in 7.17.7.
3 The
atomic_bool
type provides an atomic boolean.4 The
atomic_address
type provides atomic void * operations. The unit of addition/subtraction shall be one byte.5 NOTE The representation of atomic integer and address types need not have the same size as their corresponding regular types. They should have the same size whenever possible, as it eases effort required to port existing code.
I can only guess, but if you can implement atomic access only to things larger than uint16_t, then implementing atomic access to uint_least16_t and uint_fast16_t can always be done by defining the types accordingly, while atomic access to uint16_t may be just impossible with the available hardware. And you don't want anything in the standard that cannot be implemented.