C++编译.翻译阶段 #1.通用字符名称

C++ Compilation. Phase of translation #1. Universal character name

本文关键字:字符 编译 翻译 C++      更新时间:2023-10-16

我不明白它在 c++ 标准中是什么意思:

不在基本源字符集中的任何源文件字符 (2.3( 替换为通用字符名称,该名称指定 (一个实现可以使用任何内部编码,只要 作为源文件中遇到的实际扩展字符,以及 在源文件中表示的相同扩展字符为 通用字符名称(即使用 \uXXXX 表示法(是 等效处理,除非此替换在 原始字符串文本。

据我了解,如果编译器看到字符不在基本字符集中,则只需将其替换为这种格式的字符序列"\uNNNN">"\UNNNNNNNNNN"。但是我不知道如何获得这个NNNN或NNNNNNNN。所以这是我的问题:如何进行转换

注意前面的句子,它指出:

如有必要,物理源文件字符以实现定义的方式映射到基本源字符集(为行尾指示符引入换行符(。

也就是说,它完全取决于编译器如何实际解释构成文件的字符或字节。在执行此解释时,它必须确定哪些物理字符属于基本源字符集,哪些不属于。如果一个字符不属于,那么它将被替换为通用字符名称(或者至少,效果就像它已经完成了一样(。

这样做的目的是将源文件减少到非常小的字符集 - 基本源字符集中只有 96 个字符。任何不在基本源字符集中的字符都被替换为uU,以及一些十六进制数字(0 - F(。

通用字符名称是以下之一:

uNNNN
UNNNNNNNN

其中每个N都是十六进制数字。这些数字的含义在§2.3中给出:

通用字符名称UNNNNNNNN指定的字符是 ISO/IEC 10646 中字符短名称NNNNNNNN的字符;通用字符名称uNNNN指定的字符

是 ISO/IEC 10646 中字符短名称0000NNNN字符。如果通用字符名称的十六进制值对应于代理项代码点(在 0xD8000xDFFF 范围内,则程序格式不正确。

ISO/IEC 10646 标准起源于 Unicode 之前,定义了通用字符集 (UCS(。它将代码点分配给字符,并指定应如何对这些代码点进行编码。Unicode 联盟和 ISO 小组随后联手开发 Unicode。Unicode 标准比 ISO/IEC 10646 规定的要多得多(算法、功能字符规范等(,但这两个标准现在保持同步。

因此,您可以将NNNNNNNNNNNN视为该字符的 Unicode 代码点。

例如,考虑源文件中包含以下内容的一行:

const char* str = "Hellô";

由于 ô 不在基本源字符集中,因此该行在内部转换为:

const char* str = "Hellu00F4";

这将给出相同的结果。

代码中只有某些部分允许使用通用字符名称:

  • 在字符串文本中
  • 在字符文本中
  • 在标识符中(但是,这不是很好支持(

但是我不知道如何获得这个NNNN或NNNNNNNN。所以这是我的问题:如何进行转换?

映射是实现定义的(例如 §2.3 脚注 14(。例如,如果我将以下文件保存为 Latin-1:

#include <iostream>
int main() {
    std::cout << "Hallön";
}

并在OS X上使用g++编译它,运行后我得到以下输出:

Hell�

。但是如果我将其保存为 UTF-8,我会得到这个:

Hellö

因为 GCC 假设 UTF-8 作为我系统上的输入编码。

其他编译器可能会执行不同的映射。

因此,如果您的文件名为 Hello°¶.c ,编译将在内部使用该名称时,例如,如果我们这样做:

cout << __FILE__ << endl;

编译器会将Hello°¶.c转换为Hellou00b0u00b6.c

但是,当我刚刚尝试g++时,它并没有这样做......

但汇编程序输出包含:

.string "Hello302260302266.c"