我知道:
#define foo 4
#define str(s) #s
str(foo)
会输出 "foo"
,因为文本展开时首先执行字符串化操作。
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
使用xstr(foo)
会输出:"4"
。
为什么会这样?这个过程包含哪些步骤?
我知道:
#define foo 4
#define str(s) #s
str(foo)
会输出 "foo"
,因为文本展开时首先执行字符串化操作。
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
使用xstr(foo)
会输出:"4"
。
为什么会这样?这个过程包含哪些步骤?
#
或者 ##
开头的标记。xstr(foo)
,我们有以下步骤:
str(s)
不包含 #
或者 ##
,因此什么都不会发生。foo
被替换为 4
,因此就好像使用了 xstr(4)
。str(s)
中,参数 s
被替换为 4
,生成 str(4)
。str(4)
被重新扫描。 (产生的步骤会产生 "4"
。)str(foo)
的问题在于第2步,将 foo
替换为 4
的步骤在第1步之后,而第1步将参数更改为字符串。 在第1步中,foo
仍然是 foo
;它没有被替换为 4
,因此结果是 "foo"
。stringify
宏经常出现在许多地方(例如将__LINE__
附加到标识符上 - 强制其被扩展而不是保留为__LINE__
,在这种情况下,您将使用##
而不是#
),或者最近需要将参数传递给GCC的_Pragma()
宏(内部函数?),该宏接受带引号的字符串,因此您可能需要:#define my_pragma(arg) _Pragma(stringify("blah " #arg " blah2"))
。 - Tomasz Gandorstr(foo)
:用 #foo
替换 str(foo)
,即 "foo"
xstr(foo)
: 用 str(<foo-value>)
替换 xstr(foo)
,即 str(4)
str(4)
: 用 #4
替换 str(4)
,即 "4"
预处理器会评估宏函数并展开宏变量,直到没有可评估的内容为止:
如果你定义了
#define xstr(s) str(s) + 1
#define str(s) s + 1
在下面的代码中
#define foo 4
int main()
{
std::cout << str(foo) << '\n'
<< xstr(foo) << '\n' ;
}
将str(foo)
替换为<foo-value> + 1
,即4 + 1
结果为4 + 1
将xstr(foo)
替换为str(<foo-value>) + 1
,即str(4) + 1
str(4)
替换为<4-value> + 1
,即4 + 1
结果为4 + 1 + 1
#
吗? 这只是一步。 - Lol4t0