2010-09-23 77 views
4

可能重复:
What does “#define STR(a) #a” do?宏评估

#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()的声明不同。

回答

13

由于预处理器执行的操作的顺序,输出不同,这在C99标准的6.10.3节(以及后面的章节)中有描述。特别地,这句话从6.10.3.1/1:

在替换列表中的参数,除非前面由###预处理记号或后跟一个##预处理记号,由相应的参数之后全部替换其中包含的宏已经扩展。

所以在第一线,扩大h调用时,参数f(1,2)是之前扩大它取代h的参数a#仅在稍后重新扫描所有内容的输出时看到结果调用g时才会发挥作用。

但是在第二行中,立即看到#,并且上述引用中的“除非......之前......”子句触发不同的行为。参见the relevant C-FAQ entry

8

预处理与宏观扩张完成后,编译器看到这一点:

int main() 
    { 
     printf("%s\n","printf(\"yes\")"); 
     printf("%s\n","f(1,2)"); 
    } 

这是一种常见的技术层中的“额外”间接当你字串来控制,当你得到实际宏观评估。

基本上,宏观评估发生在“外部”,而不是相反。 wikipedia page表示“参数不首先解析宏替换”,我相信这是指同一件事情。