2011-11-27 99 views
15

當我使用此代碼:「#define STR(x)#x」和「#define STR(x)VAL(x)」與「#define VAL(x)#x」之間的區別是什麼?

#include <stdio.h> 
#define STR(x) #x 

int main(void) 
{ 
    printf(__FILE__ STR(__LINE__) "hello!\n"); 
    return 0; 
} 

它打印

hello.c__LINE__hello! 

但是當我使用這個:

#include <stdio.h> 
#define STR(x) VAL(x) 
#define VAL(x) #x 

int main(void) 
{ 
    printf(__FILE__ STR(__LINE__) "hello!\n"); 
    return 0; 
} 

它打印

hello.c7hello! 

有什麼區別其中,宏參數名稱出現在與stringifier#或令牌貼紙##的宏體參數傳遞給宏

之間
#define STR(x) #x 

#define STR(x) VAL(x) 
#define VAL(x) #x 
+0

如果您先定義VAL(X),該怎麼辦?你有相同的結果嗎? – I82Much

+0

是的,與先定義STR(x)一樣 – vv1133

+0

可能重複[宏擴展的確切步驟是什麼?](http://stackoverflow.com/questions/6742501/whats-the-exact-step-of-macro擴展) – codaddict

回答

9

本身是宏展開,除了

在第一種情況下,STR的參數是而不是宏擴展,因此您只需獲取LINE宏的名稱。

在第二種情況下,STR 的說法是宏展開時,它代入VAL的定義,所以它的工作原理 - 你得到實際的行號,因爲LINE宏展開。

0

C99 N1256 standard draft 6.10.3.1/1「參數替換」:

參數的函數宏的調用後已經確定, 參數替換髮生。除非 之前由#或##預處理令牌或後跟##預處理令牌(請參閱下文),否則替換列表中的參數 將被替換爲相應的參數,其中包含的所有宏已被 展開。在被替換之前,每個參數的預處理標記是 完全宏替換,就好像它們構成了預處理文件的其餘部分一樣;沒有其他 預處理令牌可用。

所以###使參數被區別對待。

相關問題