C ++编译。翻译阶段#1。通用角色名称

时间:2013-03-09 13:50:34

标签: c++ compiler-construction utf-8

我无法理解c ++标准中的含义:

  

任何不在基本源字符集中的源文件字符(2.3)   由指定它的通用字符名称替换   特征。 (实现可以使用任何内部编码,这么久   作为源文件中遇到的实际扩展字符,和   在源文件中表示的相同扩展字符为   通用字符名称(即使用\ uXXXX表示法)是   处理等效,除非这个替换在a。中被还原   原始字符串文字。)

据我了解,如果编译器看到charcter不在基本字符集中,它只是用这种格式的字符序列替换它'\ nNNNNN''\ UNNNNNNNN'。但我不知道如何获得这个NNNN或NNNNNNNN。 所以这是我的问题:如何进行转化

3 个答案:

答案 0 :(得分:3)

请注意前面的句子:

  

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

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

这一点是将源文件减少到一小组字符 - 基本源字符集中只有96个字符。任何不在基本源字符集中的字符都已替换为\uU,以及一些十六进制数字(0 - F)。< / p>

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

\uNNNN
\UNNNNNNNN

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

  

通用字符名\UNNNNNNNN指定的字符是ISO / IEC 10646中字符短名称为NNNNNNNN的字符;通用字符名\uNNNN指定的字符是ISO / IEC 10646中的字符短名称为0000NNNN的字符。如果通用字符名称的十六进制值对应于代理代码点(在0xD800 - 0xDFFF范围内),则该程序格式不正确。

ISO / IEC 10646标准在Unicode之前发起并定义了通用字符集(UCS)。它为字符分配了代码点,并指定了应如何编码这些代码点。然后,Unicode Consortium和ISO小组联合起来处理Unicode。 Unicode标准规定的不仅仅是ISO / IEC 10646(算法,功能字符规范等),但两种标准现在保持同步。

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

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

const char* str = "Hellô";

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

const char* str = "Hell\u00F4";

这将得到相同的结果。

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

答案 1 :(得分:2)

  

但我不知道如何获得这个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作为我系统上的输入编码。

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

答案 2 :(得分:1)

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

cout << __FILE__ << endl;

编译器会将Hello°¶.c翻译为Hello\u00b0\u00b6.c

但是,当我用g++尝试此操作时,它不会这样做......

但汇编程序输出包含:

.string "Hello\302\260\302\266.c"