C/C++宏展開順序


宏展開順序

宏展開順序大致可以歸結為:

第一步:首先用實參代替形參,將實參代入宏文本中

第二步:第一步代入實參后,分兩種情況:

1、實參之前遇到#或或之后遇到##,不管實參是不是宏,實參都將不再展開

2、如果實參前后沒有#或##,那就繼續展開實參,展開發現還是宏則繼續展開,直到展開到不能展開為止

第三步:最后繼續處理宏替換后的宏文本,如果仍包含宏,則繼續展開

參考:https://blog.csdn.net/FJDJFKDJFKDJFKD/article/details/83385708

宏展開的幾個注意事項:

1、每次宏展開的結果會被重復掃描,直到沒有任何可展開的宏為止。

2、每展開一個宏,都會記住這次展開,在這個宏展開的結果及其后續展開中,不再對相同的宏做展開。宏不能自引用:https://gcc.gnu.org/onlinedocs/cpp/Self-Referential-Macros.html

3、帶參數的宏,先對參數做展開,除非宏定義體中包含#或##

a) #表示將后續標識符轉換為字符串

b) ##表示將兩個標識符連接成一個標識符

c) 注意參數展開的結果中即使有逗號(,),也不視為參數的分隔符

如果宏定義中帶有參數,而代碼中出現同樣標識符時沒有參數,不視為宏。

參考:https://www.cnblogs.com/aquastone/p/c-macro-expansion.html
https://blog.csdn.net/KeLiaoo/article/details/109329661

編譯階段打印宏內容

首先介紹#pragma message 。 它能夠在編譯信息輸出窗口中輸出相應的信息,這對於源代碼信息的控制是非常重要的。其使用方法為:

#pragma message(“消息文本”)

假設我們希望判斷自己有沒有在源代碼的什么地方定義了_X86這個宏可以用下面的方法

#ifdef _X86
#pragma message(“_X86 macro activated!”)
#endif

下面的示例演示如何在編譯階段打印宏內容。

//兩個用於測試的宏
#define PI 3.1415926
#define MAX(a,b) (a)>(b) ? (a) :(b)


//首先定義兩個輔助宏
#define   PRINT_MACRO_HELPER(x)   #x  
#define   PRINT_MACRO(x)   #x": "PRINT_MACRO_HELPER(x)  

//編譯階段打印宏內容
#pragma message(PRINT_MACRO(PI))
#pragma message(PRINT_MACRO(PI2))
#pragma message(PRINT_MACRO(MAX(a,b)))
#pragma message(PRINT_MACRO(MAX(x,y)))

結果輸出
note: #pragma message: PI=3.1415926  
//PRINT_MACRO中的兩個x都被替換為PI,PRINT_MACRO_HELPER中的#x替換為宏PI的內容
note: #pragma message: PI2=PI2          
//PI2不存在的情況下PRINT_MACRO_HELPER將#x換做PI2
note: #pragma message: MAX(a,b)=(a)>(b) ? (a) :(b)
note: #pragma message: MAX(x,y)=(x)>(y) ? (x) :(y)

參考:https://blog.csdn.net/xshbx/article/details/7981564


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM