2010-09-23 103 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表示「參數不首先解析宏替換」,我相信這是指同一件事情。