我试图理解 C11 标准中的通用字符名称,发现 C11 标准的 N1570 草案在翻译阶段 1 和 5 以及 UCN 的形成和处理方面比 C++11 标准的细节要少得多他们。这是每个人都必须说的:
翻译阶段 1
N1570 草案 C11 5.1.1.2p1.1:
如有必要,物理源文件多字节字符以实现定义的方式映射到源字符集(为行尾指示符引入换行符)。Trigraph 序列被相应的单字符内部表示替换。
C++11 2.2p1.1:
物理源文件字符以实现定义的方式映射到基本如有必要,源字符集(为行尾指示符引入换行符)。接受的物理源文件字符集是实现定义的。三字母序列 (2.4) 被相应的单字符内部表示代替。任何不在基本源字符集 (2.3) 中的源文件字符都将替换为指定该字符的通用字符名。(实现可以使用任何内部编码,只要在源文件中遇到的实际扩展字符,以及在源文件中表示为通用字符名称的相同扩展字符(即,使用 \uXXXX 表示法)是等效处理,除非此替换在原始字符串文字中恢复。)
翻译阶段 5
N1570 草案 C11 5.1.1.2p1.5:
字符常量和字符串文字中的每个源字符集成员和转义序列都被转换为执行字符集的相应成员;[...]
C++ 2.2p1.5:
字符文字或字符串文字中的每个源字符集成员,以及字符文字或非原始字符串文字中的每个转义序列和通用字符名称,都将转换为执行字符集的相应成员;[...]
(强调差异)
问题
在 C++11 标准中,非常清楚的是,不在基本源字符集中的源文件字符被转换为 UCN,并且它们在同一位置被完全视为 UCN,唯一的例外是原始字符串。C11也是这样吗?当 C11 编译器看到多字节 UTF-8 字符(例如 )时
°
,它是否也将其转换为\u00b0
阶段 1,并将其视为\u00b0
出现在那里?换句话说,在哪个翻译阶段结束时(如果有),以下代码片段是否在 C11 中首次转换为文本等价形式?
const char* hell° = "hell°";
和
const char* hell\u00b0 = "hell\u00b0";
如果在 2. 中,答案是“没有”,那么在哪个翻译阶段,这两个标识符首先被理解为指代同一事物,尽管在文本上有所不同?
- 在 C11 中,字符/字符串文字中的 UCN 是否也在阶段 5 中转换?如果是这样,为什么从标准草案中省略这一点?
- 在 C11 和 C++11 中如何处理标识符中的 UCN(与已经提到的字符/字符串文字相反)?他们是否也在第 5 阶段转换?或者这是实现定义的东西?例如,GCC 是否以 UCN 编码形式或实际 UTF-8 打印出此类标识符?