问题描述
我正在尝试使用一些现有代码,但我遇到了这段代码,但我不太明白它是如何工作的:
char *c_token = R(
{
"1":"abcdef","2":"ghijkl","3":"mnopqr","4":"stuvwx"
});
其中 R() 定义为:
#define R(...) #__VA_ARGS__
c_token 缓冲区在这之后是什么样子的?与仅分配 map
假设这是用来传递这张地图的,你如何将它翻译回另一端的地图?
解决方法
预处理器正在将括号之间的所有内容(包括逗号)转换为字符串文字。它几乎可以是完全的语法垃圾。例如:这很好。 R(!@#,*&#,(,));
作为实验,尝试:
#define R(...) "BEGIN" #__VA_ARGS__ "END"
这产生:"BEGIN!@#,)END"
并比较当你这样做时会发生什么:
#define R(x) "BEG" #x "END"
这会产生:"BEGIN!@#END"
并带有如下警告:
类似函数的宏调用'R'的参数过多
,这里发生的是预处理器Stringification。 R()
的参数中出现的任何内容都将转换为字符串。宏参数前面的 #
是导致这种情况的语法。
所以 R("foo",abc!@#)
变成了字符串字面量 "\"foo\",abc!@#"
。换行符和前导空格将转换为单个空格。
这样做的原因是使包含大量 "
的字符串更易于编写,无需对它们进行转义,并允许更轻松的换行。如果您直接直接编写 JSON 字符串,则每个 "
都需要写为 \"
以防止它分隔字符串。每行还需要结束字符串并在下一行开始新的一行,因为字符串文字中不能有换行符。
所以这个例子可以写成:
const char *c_token =
"{"
"\"1\":\"abcdef\","
"\"2\":\"ghijkl","
"\"3\":\"mnopqr","
"\"4\":\"stuvwx""
"}";
宏允许的更自然的语法更复杂。