下面是一個相關示例。這顯然是無效的C,但我只是在這裏處理預處理器,所以代碼實際上並不需要編譯。在C宏擴展期間,是否有擴展爲「/ *」的宏的特殊情況?
#define IDENTITY(x) x
#define PREPEND_ASTERISK(x) *x
#define PREPEND_SLASH(x) /x
IDENTITY(literal)
PREPEND_ASTERISK(literal)
PREPEND_SLASH(literal)
IDENTITY(*pointer)
PREPEND_ASTERISK(*pointer)
PREPEND_SLASH(*pointer)
運行gcc的預處理器就可以了:
gcc -std=c99 -E macrotest.c
這產生了:
(...)
literal
*literal
/literal
*pointer
**pointer
/*pointer
請注意,在最後一行的額外空間。
這看起來像一個功能,防止宏擴展到「/ *」給我,我敢肯定,這是一個善意的。但是一目瞭然,我在C99標準中找不到與此行爲有關的任何內容。再次,我沒有經驗C。有人可以對此有所瞭解嗎?這在哪裏指定?我猜想一個遵循C99的編譯器不應該在宏擴展期間插入額外的空格,因爲它可能會防止編程錯誤。
+1。我認爲關鍵的見解是,-E的輸出確實沒有被標準規定。該標準討論了由一系列預處理令牌組成的程序,然後將其轉換爲令牌序列。這完全取決於預處理器如何表示這些序列,並且在這種情況下如何將它們序列化爲一個* bytes *序列的文件。當然,唯一可行的序列化是可以作爲等價的一系列預處理令牌讀回來的,所以,如你所說,它必須在兩個令牌之間放置空白,這兩個令牌形成一個。 – 2010-11-12 14:14:36
我同意100%,想寫一些像你的解釋,但沒有時間。 – 2010-11-12 15:28:55
好的答案,雖然我有兩個nitpicky的評論:沒有'''* *'標記的東西;在標記之前,註釋會從源中刪除。你可以使用'##'從兩個'+'令牌形成'++'標記。 – 2010-11-12 16:40:47