原生字符串字面量 是C++11标准引入的用于避免手动将字符串换码的新特性。
按照标准要求,其内部的一切文字都将原封不动地、所见即所得地声明为字符串。现在的问题是,预处理指令理应先于一切其他语言特性进行,在一些编译系统中(如 MinGW),预处理阶段甚至是由 cpp.exe(CPreProcessor)这一单独的程序完成的。而预处理指令处于一行开头且以#开始,如果在原生字符串字面量中的一个新行里顶头写上一句 #include 指令,会发生什么呢?
在C++98/03中,这个担心是没有必要的,因为字符串必须在一行内声明完,但由于C++11的这个新特性的提出,就产生了这一问题。事实的真相到底是什么呢?实验让你眼见为实:
//test.cpp
#include <iostream>
using namespace std;
/**测试从这里开始*/
const char str[] =
R"(
#include "example.txt"
)"
;
int main(int argc,char * argv[])
{
cout << "实际变量 str 的内容是:" << endl << str << endl;
return 0;
}
//example.txt
样例测试字符串
编译环境:Windows 7 旗舰版 Sevice Pack 1,Intel(R) Celeron(R) M CPU 723,32位操作系统,TDM-GCC-32 4.7.2。
编译选项:mingw32-g++ test.cpp -o test.exe -std=c++11
下面运行程序。
如果 #include 得到先一步执行,那么程序将输出 example.txt 的内容(试验时它的内容是“样例测试字符串”);如果编译器无视了 #include 指令,那么程序将输出如上代码中写入的“\n#include "example.txt"\n”。
运行结果是这样的:
prompt> mingw32-g++ test.cpp -o test.exe -std=c++11
prompt> test
实际变量 str 的内容是:
#include "example.txt"
显然,#include 指令并未被展开。
我们的结论是:原生字符串字面量中的一切文字,包括预处理指令,都会被看做是“纯”的、“普通”的文字,而不会发挥(它可能具有的)语义功能;而这也与标准中对它的“原生的、不加处理的”的描述相符。