为什么 char16_t 定义为与 uint_least16_t 大小相同,而不是 uint16_t?

Why is char16_t defined to have the same size as uint_least16_t instead of uint16_t?

正在阅读 C++17 草案 §6.9.1/5:

Types char16_t and char32_t denote distinct types with the same size, signedness, and alignment as uint_least16_t and uint_least32_t, respectively, in <cstdint>, called the underlying types.

现在参考C11草案§7.20.1.2/2,这是C库继承的参考:

The typedef name uint_leastN_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.

注意 "at least" 部分。这意味着 char16_t 实际上可能有例如32 位,使 char16_t 的数组无法很好地表示 UTF-16 原始数据。在这种情况下,将这样的数组写入二进制文件将导致有效代码单元与 U+0000 个字符交替出现。

uint_least16_t 而不是 uint16_t 来定义 char16_t 是否有充分的理由?或者它只是标准中的一个缺陷?

这使得在字节大小不是 16 的因数(例如 32 位字节或 9 位字节)的系统上使用 char16_t 成为可能。这样的系统可以有 uint_least16_t 但没有 uint16_t

首先,顾名思义,uint_least16_t要求是最小的可以容纳16位的大小。在同时具有 16 位和 32 位整数的系统上,它 不能 是 32 位。

其次,uint16_t不需要存在。它只存在于具有 16 位整数类型的系统上。诚然,这些很常见,但 C 和 C++ 旨在对它们可以针对的硬件施加最小限制,并且有些系统没有 16 位整数类型。

在具有 16 位整数类型的系统上,uint16_t 将是 16 位宽(duh...),并且 uint_least16_t 也将是 16 位宽。在没有 16 位整数类型的系统上,uint16_t 将不存在,而 uint_least16_t 将存在。对于需要将值存储在可表示为 16 位的范围内的代码,使用 uint_least16_t 是可移植的。对于需要存储 exactly 16 位(很少见)的代码,uint16_t 是可行的方法。