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