为什么stdatomic.h包含atomic_uint_least16_t和atomic_uint_fast16_t,而不包含atomic_uint16_t?

vfh0ocws  于 2023-08-03  发布在  其他
关注(0)|答案(3)|浏览(124)

stdatomic.h appears to containatomic_uint_least16_tatomic_uint_fast16_t,是stdint.h typesuint_least16_tuint_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名称。
这意味着,例如,如果我有一个像intshort这样的类型,它被实现为一个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 * 操作。加/减的单位应为一个字节。
原子整数和地址类型的表示不需要与它们对应的常规类型具有相同的大小。它们应该尽可能具有相同的大小,因为这样可以简化移植现有代码所需的工作。

jhiyze9q

jhiyze9q1#

这个专门的原子类型列表只是因为一个历史性的事故而存在,它们旨在确保与C++的兼容性。而且,它们只是为强制性的整数类型提供接口。uintXX_t类型都不是强制性的,因此不包括它们。
(That通过添加atomic_[u]intprt_t(其中[u]intptr_t * 不是 * 强制性的),目标立即被稀释,但这可能是另一个故事。

11dmarpk

11dmarpk2#

因为平台可能无法以原子方式处理uint16_t。如果一个平台没有原生的uint16_t类型,编译器仍然可以在uint32_t之上模拟该类型,但这样的模拟类型永远不会是原子的。
请注意,所有精确宽度类型都是可选的。C标准只要求uint_least16_tuint_fast16_t存在。两者都保证具有至少16位,但它们可以具有多于16位。不同之处在于,第一个是针对空间优化的(使用尽可能少的内存,即使这会很慢),第二个是针对性能优化的(使用可用的最快类型,即使这需要大量内存)。
编译器可以提供uint16_t,如果这样的原生类型在平台上可用,或者编译器想要模拟它,但从来没有要求这样做。代码应该可以用遵循标准的每个编译器编译,首先不能依赖于uint16_t
POSIX标准要求uint16_t存在,因此对于POSIX平台,编译器必须模拟该类型本身不可用,但POSIX平台根本不要求任何类型是原子的。

uwopmtnx

uwopmtnx3#

我只能猜测,但如果你只能对大于uint16_t的对象实现原子访问,那么对uint_least16_t和uint_fast16_t的原子访问总是可以通过相应地定义类型来实现,而对uint16_t的原子访问可能在可用的硬件上是不可能的。你不希望标准中有任何不能实现的东西。

相关问题