首页 > 解决方案 > C++20 'char8_t' 和我们的旧 'char' 一样吗?

问题描述

在 CPP 参考文档中,

我注意到char

字符类型足够大,可以表示任何 UTF-8 八位代码单元(C++14 起)

并且对于char8_t

用于 UTF-8 字符表示的类型,需要足够大以表示任何 UTF-8 代码单元(8 位)

这是否意味着两者是同一类型?还是char8_t有其他一些功能?

标签: c++c++14c++20

解决方案


免责声明:我是char8_t P0482P1423提案的作者。

在 C++20 中,char8_t是与所有其他类型不同的类型。在 C 的相关提案中,N2653char8_t一个 typedef,unsigned char类似于现有的 typedefchar16_tchar32_t

在 C++20 中,char8_t具有与unsigned char. 因此,它具有与 相同的大小(至少 8 位,但可能更大)、对齐和整数转换等级unsigned char,但具有不同的别名规则。

特别是,char8_t没有添加到[basic.lval]p11的类型列表中。[basic.life]p6.4[basic.types]p2[basic.types]p4。这意味着,与 不同unsigned char,它不能用于其他类型对象的底层存储,也不能用于检查其他类型对象的底层表示;换句话说,它不能用于给其他类型起别名。char8_t这样做的结果是可以通过指向charor的指针访问类型的对象unsigned char,但char8_t不能使用指向的指针访问charorunsigned char数据。换句话说:

reinterpret_cast<const char   *>(u8"text"); // Ok.
reinterpret_cast<const char8_t*>("text");   // Undefined behavior.

具有这些属性的不同类型的动机是:

  1. 为 UTF-8 字符数据与字符数据提供不同的类型,其编码取决于区域设置或需要单独的规范。

  2. 启用普通字符串文字与 UTF-8 字符串文字的重载(因为它们可能具有不同的编码)。

  3. 确保 UTF-8 数据的无符号类型(char有符号或无符号由实现定义)。

  4. 通过非混叠类型实现更好的性能;优化器可以更好地优化不给其他类型起别名的类型。


推荐阅读