C++:Unicode 字符串文字的可移植性

C++: portability of Unicode string literals

在 gcc 上调试时,我发现 Unicode 文字 u"万不得已" 被表示为 u"[=12=]76567725"。这是有道理的—— 是 0x4E07,八进制的 0x4E 是 116。

现在,在 Intel 驱动的 Macbook 上的 Apple LLVM 9.1.0 上,我发现相同的文字不作为相同的字符串处理,即:

u16string{u"万不得已"} == u16string{u"[=10=]76567725"}

true 变为 false。我还在小端系统上,所以我不明白发生了什么。

注意。我没有尝试使用 u"万不得已" == u"[=12=]76567725" 的对应关系。我只是想了解发生了什么。

I found that the Unicode literal u"万不得已" was represented as u"[=14=]76567725"

不,实际上不是。这就是为什么...

u"..." 字符串文字在所有平台上都被编码为基于 char16_t 的 UTF-16 编码字符串(这就是 u 前缀的具体含义)。

u"万不得已" 由这个 UTF-16 代码单元序列表示:

4E07 4E0D 5F97 5DF2

在小端系统上,UTF-16 序列由以下原始字节序列表示:

07 4E 0D 4E 97 5F F2 5D

在八进制中,仅当使用基于 char 字符串时,才会由 "[=19=]76567725" 表示(注意缺少字符串前缀,或者u8 也适用于此示例)。

u"[=14=]76567725" 不是基于 char 的字符串!它是一个基于 char16_t 字符串,其中每个八进制数代表一个单独的 UTF-16 代码单元。因此,这个字符串实际上表示这个 UTF-16 代码单元序列:

0007 004E 000D 004E 0097 005F 00F2 005D

这就是为什么您的两个 u16string 对象没有作为相同的字符串值进行比较。因为他们真的不平等。

您可以在此处查看实际效果:Live Demo