【问题标题】:Why is char16_t defined to have the same size as uint_least16_t instead of uint16_t?为什么将 char16_t 定义为与 uint_least16_t 而不是 uint16_t 的大小相同?
【发布时间】:2018-11-30 14:44:04
【问题描述】:

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

类型char16_tchar32_t 分别表示与<cstdint> 中的uint_least16_tuint_least32_t 具有相同大小、符号和对齐方式的不同类型,称为基础类型。

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

typedef 名称uint_leastN_t 指定一个宽度至少为 N 的无符号整数类型,这样任何具有较小大小的无符号整数类型都至少具有指定的宽度。因此,uint_least16_t 表示宽度至少为 16 位的无符号整数类型。

注意“至少”部分。这意味着 char16_t 实际上可能有例如32 位,使char16_t 的数组成为 UTF-16 原始数据的错误表示。在这种情况下,将这样的数组写入二进制文件会导致有效的代码单元与 U+0000 个字符交替出现。

是否有充分的理由将char16_t 定义为uint_least16_t 而不是uint16_t?还是仅仅是标准的缺陷?

【问题讨论】:

  • @PanagiotisKanavos 与char16_t的大小无关
  • Here's an example 其中uint_least16_t 将使用 18 位。
  • @GiacomoCatenazzi 见上面 Bo Persson 的评论。坦率地说,当前的过时对于 C 或 C++ 标准无关紧要。注意例如他们在指定二进制补码行为而不强制执行实际二进制补码时遇到的麻烦。
  • @PanagiotisKanavos char16_t 不必包含 UTF-16 字符。它只必须包含一个 UTF-16 代码单元,它始终是 16 位。
  • @GiacomoCatenazzi 不同意您的“C 不是为了对所有 CPU 通用而创建的”。如果您所暗示的情况正好相反,那么它将以比现在更简单的措辞指定更多的细节。甚至没有指定字节/char 的大小这一事实完全使该语句无效。

标签: c++ unicode types utf-16


【解决方案1】:

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

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

在具有 16 位整数类型的系统上,uint16_t 将是 16 位宽(呃……),uint_least16_t 也将是 16 位宽。在没有 16 位整数类型的系统上,uint16_t 将不存在,uint_least16_t 将存在。对于需要将值存储在可以 16 位表示的范围内的代码,使用 uint_least16_t 是可移植的。对于需要准确存储 16 位(这种情况很少见)的代码,uint16_t 是可行的方法。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • @PanagiotisKanavos 但是,UTF-16 代码单元始终是 16 位,这更相关,因为 char16_t 存储一个代码单元。它也不是特定于机器的。
    • @PanagiotisKanavos 您似乎误解了编码的“代码单元”和 unicode“代码点”之间的区别。从您链接的文章中(强调我的):“在 UTF-16 中,大于或等于 2^16 的 代码点 使用两个 16 位 代码单元 进行编码”
    • @PanagiotisKanavos 不,我们不是(至少 user2079303 而我不是)。 char16_t 用于存储代码单元,而不是字符。因此 C++ 标准对其进行了最宽松的定义:必须能够保存至少 16 位。哪个就够了。
    • char16_t 具有固定大小,因为它是C++ 类型u"?"char16_t[3] 文字。 u'?' 格式错误
    • @PanagiotisKanavos 如果您指的是其他编程语言,char16_t 的规范不会影响在其他语言中使用 unicode 的难易程度。他们的标准库可能会提供更多的工具来处理它,但程序员仍然需要了解代码点、字符和字素之间的差异。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-18
    • 2019-03-04
    • 1970-01-01
    • 2022-08-19
    • 2011-09-20
    • 2012-12-20
    • 2023-03-20
    相关资源
    最近更新 更多