stdatomic.h
appears to containatomic_uint_least16_t
和atomic_uint_fast16_t
,是stdint.h
typesuint_least16_t
和uint_fast16_t
的_Atomic
版本,但不包含atomic_uint16_t
。为什么
有关N1548草案的一些背景信息:
7.18.1.1精确宽度整数类型
1 typedef名称int
N _t
指定宽度为N的有符号整数类型,无填充位,并使用二进制补码表示。因此,int8_t
表示这样一个带符号整数类型,其宽度正好为8位。
2 typedef名称uint
N _t
指定宽度为N且无填充位的无符号整数类型。因此,uint24_t
表示这样一个宽度正好为24位的无符号整数类型。
3这些类型是可选的。然而,如果一个实现提供了宽度为8、16、32或64位的整数类型,没有填充位,并且(对于有符号类型)具有二进制补码表示,则应定义相应的typedef名称。
7.18.1.2最小宽度整数类型
1 typedef名称int_least
N _t
指定一个宽度至少为N的有符号整数类型,因此没有较小大小的有符号整数类型具有至少指定的宽度。因此,int_least32_t
表示宽度至少为32位的有符号整数类型。
2 typedef名称uint_least
N _t
指定一个宽度至少为N的无符号整数类型,因此没有更小的无符号整数类型具有至少指定的宽度。因此,uint_least16_t
表示宽度至少为16位的无符号整数类型。
3需要以下类型:
int_least8_t
int_least16_t
int_least32_t
int_least64_t
uint_least8_t
uint_least16_t
uint_least32_t
uint_least64_t
字符串
此表单的所有其他类型都是可选的。
(and以此类推,以包括int_fast
N _t
/uint_fast
N _t
类型等)
第3段值得强调的是:
然而,如果一个实现提供了宽度为8、16、32或64位的整数类型,没有填充位,并且(对于有符号类型)具有二进制补码表示,则应定义相应的typedef名称。
这意味着,例如,如果我有一个像int
或short
这样的类型,它被实现为一个16位整数,用2的补码表示,那么实现应该定义int16_t
。<stdatomic.h>
的atomic_
类型也在N1548中列出(如下所示),但它没有相应的要求,即如果实现有int16_t
,那么就有atomic_int16_t
-这就是我的问题的本质。
7.17.6原子整数和地址类型
1对于下表中的每一行,原子类型名称都声明为相应的直接类型。
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这些类型上的操作的语义在7.17.7中定义。
3 atomic_bool
类型提供了一个原子布尔值。
4 atomic_address
类型提供原子void * 操作。加/减的单位应为一个字节。
原子整数和地址类型的表示不需要与它们对应的常规类型具有相同的大小。它们应该尽可能具有相同的大小,因为这样可以简化移植现有代码所需的工作。
3条答案
按热度按时间jhiyze9q1#
这个专门的原子类型列表只是因为一个历史性的事故而存在,它们旨在确保与C++的兼容性。而且,它们只是为强制性的整数类型提供接口。
uintXX_t
类型都不是强制性的,因此不包括它们。(That通过添加
atomic_[u]intprt_t
(其中[u]intptr_t
* 不是 * 强制性的),目标立即被稀释,但这可能是另一个故事。11dmarpk2#
因为平台可能无法以原子方式处理
uint16_t
。如果一个平台没有原生的uint16_t
类型,编译器仍然可以在uint32_t
之上模拟该类型,但这样的模拟类型永远不会是原子的。请注意,所有精确宽度类型都是可选的。C标准只要求
uint_least16_t
和uint_fast16_t
存在。两者都保证具有至少16位,但它们可以具有多于16位。不同之处在于,第一个是针对空间优化的(使用尽可能少的内存,即使这会很慢),第二个是针对性能优化的(使用可用的最快类型,即使这需要大量内存)。编译器可以提供
uint16_t
,如果这样的原生类型在平台上可用,或者编译器想要模拟它,但从来没有要求这样做。代码应该可以用遵循标准的每个编译器编译,首先不能依赖于uint16_t
。POSIX标准要求
uint16_t
存在,因此对于POSIX平台,编译器必须模拟该类型本身不可用,但POSIX平台根本不要求任何类型是原子的。uwopmtnx3#
我只能猜测,但如果你只能对大于uint16_t的对象实现原子访问,那么对uint_least16_t和uint_fast16_t的原子访问总是可以通过相应地定义类型来实现,而对uint16_t的原子访问可能在可用的硬件上是不可能的。你不希望标准中有任何不能实现的东西。