C++ 当通过连接创建原始字符串时,是否恢复trigraph替换?
在编译时使用宏和令牌连接在宽字符串和窄字符串之间切换是非常常见的C++ 当通过连接创建原始字符串时,是否恢复trigraph替换?,c++,c++11,C++,C++11,在编译时使用宏和令牌连接在宽字符串和窄字符串之间切换是非常常见的 #define _T(x) L##x const wchar_t *wide1 = _T("hello"); const wchar_t *wide2 = L"hello"; 在C++11中,将类似的东西与原始字符串混合应该是有效的: #define RAW(x) R##x const char *raw1 = RAW("(Hello)"); const char *raw2 = R"(Hello)"; 由于宏扩展和令牌连接发
#define _T(x) L##x
const wchar_t *wide1 = _T("hello");
const wchar_t *wide2 = L"hello";
在C++11中,将类似的东西与原始字符串混合应该是有效的:
#define RAW(x) R##x
const char *raw1 = RAW("(Hello)");
const char *raw2 = R"(Hello)";
由于宏扩展和令牌连接发生在转义序列替换之前,因此应防止在带引号的字符串中替换转义序列
但这如何适用于三角图呢?通过与普通字符串连接形成的原始字符串是否仍要恢复其trigraph替换
const char *trigraph = RAW("(??=)"); // Is this "#" or "??="?
三角图替换发生在宏处理之前 UPD请忽略这一点。我还没有意识到c++0x可以还原原始字符串文本中的三角图
UPD2 2.5.3描述了形成原始字符串文字预处理标记的过程。三角图反转是这个过程的一部分。没有不是预处理标记的原始字符串文本。因此,您的问题的答案似乎是肯定的。否,在您的示例中,三角图没有还原。
[lex.phases]p1
确定了与您的问题相关的三个翻译阶段:
一,。Trigraph序列由相应的单字符内部表示替换。3.源文件被分解为预处理令牌。
4.宏调用被展开 阶段1由
[lex.trigraph]p1
定义。在此阶段,您的代码将被转换为const char*trigraph=RAW((#))
阶段3由[lex.pptoken]
定义。这是以原始字符串文字还原三角图的阶段。第3段说:
如果下一个字符开始的字符序列可能是原始字符串文字(如R)的前缀和初始双引号,则下一个预处理标记应为原始字符串文字。在原始字符串的初始和最终双引号字符之间,在第1和第2阶段执行的任何转换(三角图、通用字符名和行拼接)将恢复
在您的示例中并非如此,因此trigraph不会被还原。您的代码将转换为预处理令牌序列const
*
=
(
)”
最后,在第4阶段,扩展RAW
宏并进行令牌粘贴,从而产生以下预处理令牌序列:const
char
*
=
R”(#)"
。字符串文字的r-char序列包含一个#
。第3阶段已经发生,并且没有其他点会发生三角图反转。在编译器中尝试这个过程需要多长时间,而不是在这里问这个问题所花费的时间?我不想在生产代码中使用它,我正在编写一个编译器和它似乎是一种边缘情况。此外,我还不知道有哪种编译器具有完全的C++0x支持(而且我认为最终的标准还没有发布)“达米安”这不是一个合适的答案。C++的编译器知道从SPECI中发散,理解在宏处理之前发生替换,但是标准是指/或恢复/用于原始字符串文字。因为原始字符串文字只在稍后形成(作为级联的结果)。,我很好奇情况是否仍然如此。