#include <stdio.h>
#define f(a,b) printf("yes")
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n",h(f(1,2)));
printf("%s\n",g(f(1,2)));
}
有人可以解释为什么输出是两个printf()的声明不同。
#include <stdio.h>
#define f(a,b) printf("yes")
#define g(a) #a
#define h(a) g(a)
int main()
{
printf("%s\n",h(f(1,2)));
printf("%s\n",g(f(1,2)));
}
有人可以解释为什么输出是两个printf()的声明不同。
由于预处理器执行的操作的顺序,输出不同,这在C99标准的6.10.3节(以及后面的章节)中有描述。特别地,这句话从6.10.3.1/1:
在替换列表中的参数,除非前面由
#
或##
预处理记号或后跟一个##
预处理记号,由相应的参数之后全部替换其中包含的宏已经扩展。
所以在第一线,扩大h
调用时,参数f(1,2)
是之前扩大它取代h
的参数a
。 #
仅在稍后重新扫描所有内容的输出时看到结果调用g
时才会发挥作用。
但是在第二行中,立即看到#
,并且上述引用中的“除非......之前......”子句触发不同的行为。参见the relevant C-FAQ entry。
预处理与宏观扩张完成后,编译器看到这一点:
int main()
{
printf("%s\n","printf(\"yes\")");
printf("%s\n","f(1,2)");
}
这是一种常见的技术层中的“额外”间接当你字串来控制,当你得到实际宏观评估。
基本上,宏观评估发生在“外部”,而不是相反。 wikipedia page表示“参数不首先解析宏替换”,我相信这是指同一件事情。