如果我有:#define in #define;預處理器中發生了什麼?
#define X 5
#define Y X
在預處理會發生什麼爲樣的事情? 它是否經歷整個文件並將每個X更改爲5, 然後回到下一個定義,然後將每個Y更改爲5(因爲在前一次迭代中Y得到5)?
如果我有:#define in #define;預處理器中發生了什麼?
#define X 5
#define Y X
在預處理會發生什麼爲樣的事情? 它是否經歷整個文件並將每個X更改爲5, 然後回到下一個定義,然後將每個Y更改爲5(因爲在前一次迭代中Y得到5)?
C標準有一個關於宏如何擴展的特殊術語。
宏名實際上存儲在「此時定義的所有宏」的大表中。左側的每個表格條目「宏名稱」(以及中間的任何參數)和右側的「擴展令牌流」。
當宏要被擴展(因爲它發生在一些非預處理線中,或者在一個預處理線,其中它必須擴大的位置 - 例如,可以#define STDIO <stdio.h>
然後),表條目是「塗成藍色」,然後讀取替換的標記流(參數擴展也由標準規定)。
如果更換令牌流包含原始宏的名稱,它不再匹配,因爲「藍漆」掩蓋了名。
當更換令牌流已經完全處理,「藍漆」被刪除,重新露出了名。
因此:
#define X 5
增加X
:(無參數),5
到表中。
然後:
#define Y X
補充說:Y
:(無參數),X
表。
文件中的某個地方之後,你可能有令牌Y
的發生。假定既沒有上述已#undef
ED(從表中刪除),編譯器必須首先「塗料的Y
藍色表項」,並與令牌X
替換令牌Y
。
接下來,編譯器必須「繪製X
藍色的表格條目」,並用標記5
替換標記X
。
令牌5
不是預處理器宏名稱(它不能被定義),因此令牌5
超出了預處理階段的範圍。現在,從「X
」表格條目中刪除「藍色油漆」,就像這樣;然後從Y
條目中刪除「藍色油漆」,這也完成了。
如果你是不是寫:
#define Y Y, Y, Y, the letter is called Y!
那麼序列,在遇到後面的標記Y
,應該是:
Y
藍色Y
,
Y
,
Y
,
the
letter
is
called
Y
!
Y
被塗成藍色的那些不匹配,並且,
無法比擬的,所以這些都轉嫁到編譯器的休息; the
,letter
,is
和called
必須檢查,但可能不在表中,因此傳遞; Y
仍然被塗成藍色,因此不匹配並被傳遞,並且!
無法匹配並被傳遞。
你試過了嗎?它不應該超過半分鐘。發生了什麼? – Jon
用gcc -E編譯你的代碼,你可以看到預處理器產生了什麼樣的代碼 – MOHAMED