【发布时间】:2019-08-02 11:32:43
【问题描述】:
我想在header文件中放一个常量json字符串,这样其他来源也可以使用和查看。我想在 C++11 中使用原始字符串文字,因为它看起来清晰漂亮。但是,我尝试使用 gcc 4.8.5/gcc 4.9.2 编译以下代码,使用 gcc -std=c++11 test.cpp:
#include <cstdio>
/* works, but looks ugly */
#define STR_a \
"{ \n\
\"AAA\": \"a\", \n\
\"BBB\": \"b\" \n\
}"
/* works with VS2017, not works with gcc */
#define STR_b \
R"({
"AAA": "a",
"BBB": "b"
})";
/* works, but must use 'extern const'/'static' in header files */
const char *STR_var = 1 + R"(
{
"AAA": "a",
"BBB": "b"
})";
int main()
{
const char *s = STR_b;
printf("%s\n", s);
return 0;
}
但是,我得到编译错误:
test.cpp:16:1:错误:未终止的原始字符串 R"({ ^ test.cpp:19:3:警告:缺少终止“字符 })"; ^ test.cpp:19:1:错误:缺少终止“字符 })"; ^ test.cpp:29:2:错误:程序中出现杂散“R”如果我添加反斜杠,gcc 可以工作:
#define STR_b \
R"({ \
"AAA": "a", \
"BBB": "b" \
})";
但它显示错误的字符串:
{ \ “AAA”:“一个”,\ “BBB”:“b”\ }它是实现定义的功能吗?更高版本的 gcc 是否支持此功能?
编辑:
我下载并编译了 gcc 7.3.1 源代码,然后再次尝试了我的测试代码;但是,gcc7.3.1 报告与 gcc 4.X 相同的错误。我放弃了,决定继续使用static const char *。 @lyang 的回答也不错,让我大开眼界。
【问题讨论】:
-
原始字符串是 C++ 编译器的一个特性,预处理器(可能)不知道该特性。然而,我在这里和那里发现了不同预处理器之间的一些细微差别,所以你可能会找到一个可以让你这样做的,但它肯定不是标准的。您展示的“丑陋”方式是唯一安全的方式。
-
在这里使用
static const char*变量有什么问题? -
@Frank 是的,到目前为止我在头文件中使用了
static const char *变量,但我更喜欢原始字符串。如果新版本的gcc支持这个功能,我会升级gcc,然后马上替换部分代码。 -
@TaoSfqh 这是一个正交问题。您可以将原始字符串分配给
static const char*。现在,如果您的意思是字符串文字,那么您就被误导了。重复的相同文字将导致相同的结果,只是编译器需要做更多的工作。 -
@Frank 抱歉我的表达不清楚。
static使包含此标头的任何源文件都具有此变量的一个副本,我尽量避免此缺陷。如果我改用extern const char *,我必须将常量字符串放入一个源中,但我希望人们可以在头文件中看到它。