預期這不起作用:宏擴展的確切步驟是什麼?
#define stringify(x) #x
printf("Error at line " stringify(__LINE__));
這工作:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
printf("Error at line " stringify(__LINE__));
那是什麼預處理用來擴大這些宏的優先級?
預期這不起作用:宏擴展的確切步驟是什麼?
#define stringify(x) #x
printf("Error at line " stringify(__LINE__));
這工作:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
printf("Error at line " stringify(__LINE__));
那是什麼預處理用來擴大這些宏的優先級?
當擴展宏,預處理器擴展宏的參數僅當這些參數不經受字符串化(#
)或標記粘貼(##
)運營商。所以,如果你有這樣的:
#define stringify(x) #x
stringify(__LINE__)
然後,預處理程序所做的不擴大__LINE__
,因爲它是字符串化操作的參數。但是,當你這樣做:
#define stringify1(x) #x
#define stringify(x) stringify1(x)
stringify(__LINE__)
然後,擴大stringify
時,預處理器擴展__LINE__
當前的行號,因爲x
不與的stringify
定義無論是字符串化或標記粘貼的操作者使用。然後它擴大stringify1
,我們得到我們想要的。
C99標準的相關語言來自§6.10.3.1/ 1:
參數的函數宏的調用後已經確定,參數替換髮生。替換列表中的參數除非在前面加上
#
或##
預處理令牌或後跟##
預處理令牌(見下文),否則在擴展包含在其中的所有宏之後,替換爲相應的參數。在被替換之前,每個參數的預處理標記完全被宏代替,就好像它們構成了預處理文件的其餘部分一樣;沒有其他預處理令牌可用。
條款§6.10.3.2和6.10.3.3去分別定義#
和##
運營商的行爲。
特別處理'#'和'##'的理由是什麼? –
請參閱[GCC C預處理器文檔](http://gcc.gnu.org/onlinedocs/cpp/)。您將特別對[字符串化]部分感興趣(http://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification)。 – ughoavgfhw
[#define STR(x)#x「和」#define STR(x)VAL(x)「與宏」#define VAL(x)#x「之間的區別是什麼?](http: //stackoverflow.com/questions/8283596/whats-the-difference-between-the-macros-define-strx-x-and-define-strx) –