use*_*522 3 c++ unicode language-lawyer c++23
考虑以下十六进制表示的字节序列(ASCII 解释,如果有,在第二列中作为阅读辅助):
\n0x73 s\n0x74 t\n0x61 a\n0x74 t\n0x69 i\n0x63 c\n0x5f _\n0x61 a\n0x73 s\n0x73 s\n0x65 e\n0x72 r\n0x74 t\n0x28 (\n0x55 U\n0x27 \'\n0xe2\n0x84\n0xab\n0x27 \'\n0x3d =\n0x3d =\n0x55 U\n0x27 \'\n0xc3\n0x85\n0x27 \'\n0x29 )\n0x3b ;\nRun Code Online (Sandbox Code Playgroud)\n此字节序列解码为 UTF-8 读取
\nstatic_assert(U\'\xe2\x84\xab\'==U\'\xc3\x85\');\nRun Code Online (Sandbox Code Playgroud)\n请注意,左侧\xe2\x84\xab是 Unicode 标量值
0x212B ANGSTROM SIGN\nRun Code Online (Sandbox Code Playgroud)\n右侧\xc3\x85是 Unicode 标量值
0x00C5 LATIN CAPITAL LETTER A WITH RING ABOVE\nRun Code Online (Sandbox Code Playgroud)\n当字节序列被解释为强制支持的 UTF-8 编码中的源时,断言在 C++23 中是否应该失败?
\n在翻译阶段1,将UTF-8序列解码为Unicode标量值序列后,这些标量值应该映射到翻译字符集的元素以形成翻译字符集元素的序列,请参阅[ lex.phases] /1.1 . 根据[lex.charset]/1.1,除了未分配的标量值之外,翻译字符集的元素是具有分配的 Unicode 代码点的抽象字符。
\n我能找到的最接近抽象字符的定义是 Unicode 标准。然而,根据其第 3.4 章。D11 一个抽象字符可以分配多个代码点,并以 Angstrom 字符为例。(编辑:再次仔细阅读,它没有说“分配”,只是“对应于”。)
\n如果这是 C++ 标准草案中抽象字符的定义,那么翻译字符集中是否应该只有一个元素相当于由代码点 0x212B 和 0x00C5 表示的单个抽象字符?如果是这样,那么两个字符文字的值不应该相同吗,因为该值是从不保留有关原始标量值的任何信息的翻译字符集元素派生的?
\n这似乎不是我的意图。Unicode 是否提供了有关哪些代码点引用同一抽象字符的完整信息?那么,标准草案中的抽象字符到底是什么意思呢?
\n这个问题实际上是关于“抽象字符”的真正含义。这是由 Unicode 标准定义的。
\n您引用了一个抽象字符可能映射到多个代码点。甚至是代码点序列。
\n问题是该标准的其余部分似乎并不同意。
\n如果您查看 Unicode 表(也在 Unicode 标准中定义),您会发现没有关于“U+212B”或“U+00C5”的规范,它们编码为相同的抽象字符。U+212B 的条目显示:
\n\n\n\xe2\x80\xa2 首选表示形式是 00C5 \xc3\x85\n\xe2\x89\xa1 00C5 \xc3\x85 上面带环的拉丁文大写字母 a
\n
然而,\xe2\x89\xa1 符号被定义为“规范分解映射”。如果你去词汇表查一下,你会发现这并没有说明抽象字符是什么。
\n事实上,如果你查看术语表,你可能会偶然发现“角色名称”的定义:
\n\n\n角色名字。用于标识标准中编码的每个抽象字符的唯一字符串。(参见第 3.3 节“语义”中的定义 D4。)
\n
因此,每个“在标准中编码的”“抽象字符”都有一个与之关联的“唯一字符串”。
\n因此,如果“U+212B”和“U+00C5”具有不同的“字符名”属性,那么它们一定是不同的抽象字符。
\n如果您在 Unicode 字符数据库中查找它们,您会发现它们实际上具有不同的“字符名称”。因此,它们是不同的“抽象字符”,具有不同的 Unicode 代码点,因此比较不相等。
\n这与 Unicode 标准引用部分中给出的示例相矛盾。所以问题是Unicode标准本身不一致。定义映射的数据库与部分文本不一致。
\n这很可能是标准中唯一声称多个代码点映射到同一抽象字符的地方。
\n话虽这么说,我想说 C++ 标准应该使用术语“编码字符”而不是“抽象字符”。前者明确无误地指分配给字符的特定代码点。请注意,即使“编码字符”的定义也没有认识到多个代码点映射到抽象字符的可能性:“在抽象字符和代码点之间”。这些都是单一的。
\n