规范说明在编译阶段1
不在基本源字符集(2.3)中的任何源文件字符将替换为指定该字符的通用字符名称。
在第4阶段它说
执行预处理指令,扩展宏调用
在第5阶段,我们有
字符文字或字符串文字中的每个源字符集成员,以及字符文字或非原始字符串文字中的每个转义序列和通用字符名称,都将转换为执行的相应成员字符集
对于#
运算符,我们有
在字符文字或字符串文字的每个
\
和"
字符之前插入\
字符(包括分隔"
字符)。
因此我进行了以下测试
#define GET_UCN(X) #X
GET_UCN("€")
输入字符集为UTF-8(匹配我的文件的编码),我期望#X
操作的以下预处理结果:"\"\\u20AC\""
。 GCC,Clang和boost.wave不会将€
转换为UCN,而是生成"\"€\""
。我觉得我错过了什么。你能解释一下吗?
答案 0 :(得分:1)
这只是一个错误。 §2.1/ 1谈到阶段1,
(实现可以使用任何内部编码,只要在源文件中遇到实际的扩展字符,并在源文件中表示为与通用字符名称相同的扩展字符(即使用\ uXXXX表示法) ,等同处理。)
这不是注释或脚注。 C ++ 0x为原始字符串文字添加了一个例外,如果你有问题,可以解决你手头的问题。
该程序清楚地证明了故障:
#include <iostream>
#define GET_UCN(X) L ## #X
int main() {
std::wcout << GET_UCN("€") << '\n' << GET_UCN("\u20AC") << '\n';
}
因为两个字符串都很宽,所以如果编译器无法解释输入的多字节序列,则需要将第一个字符串损坏为多个字符。在您给出的示例中,完全缺乏对UTF-8的支持可能会导致编译器直接回显序列。
答案 1 :(得分:-1)
“和字符文字中的通用字符名称或非原始字符串文字,将转换为执行字符集的相应成员”
过去是
“或字符文字和字符串文字中的通用字符名称将转换为执行字符集的成员”
也许您需要未来版本的g ++。
答案 2 :(得分:-1)
我不确定你在第1阶段的引文中得到了什么 - C99 standard对§5.1.1.2/ 1中的翻译阶段1说了这句话:
物理源文件多字节字符以实现定义的方式映射到源字符集(如果需要,引入行尾指示符的换行符)。 Trigraph序列由相应的单字符内部表示替换。
因此,在这种情况下,欧元字符€(表示为UTF-8中的多字节序列E2 82 AC)被映射到执行字符集,其也恰好是UTF-8,因此其表示保持不变。它没有被转换成通用的角色名称,因为,没有任何东西可以说它应该。
答案 3 :(得分:-2)
我怀疑你会发现欧元符号不符合条件Any source file character not in the basic source character set
所以你引用的其他文字不适用。
使用您喜欢的二进制编辑器打开您的测试文件,并检查用于表示欧元符号的值GET_UCN("€")