我想用預處理器評論一行:爲什麼預處理器給出空間?
#define open /##*
#define close */
main()
{
open commented line close
}
當我做$gcc -E filename.c
我預計
/* commented line */
,但我得到了
/ * commented line */
,這樣編譯器顯示的錯誤
爲什麼它給一個不想要的sp王牌?
我想用預處理器評論一行:爲什麼預處理器給出空間?
#define open /##*
#define close */
main()
{
open commented line close
}
當我做$gcc -E filename.c
我預計
/* commented line */
,但我得到了
/ * commented line */
,這樣編譯器顯示的錯誤
爲什麼它給一個不想要的sp王牌?
預處理器以C編譯器可以理解的形式運行並生成代碼。它只處理你的代碼一次,所以即使你的可能產生/*
與你的#define
,編譯器會看到/*
並給你一個錯誤,因爲它不是有效的C代碼(這是一個預處理指令)。
這似乎不是一件很好的事情。
'#define'是這裏唯一的預處理指令。 '/ *'不是預處理器指令,但不清楚你指的是什麼。 – Potatoswatter 2010-03-06 08:01:19
@Patatoswatter:在將代碼傳遞給編譯器之前,預處理器負責刪除註釋。 – 2010-03-06 08:30:06
根據C99 5.1.1.2/3,註釋是空格,不是預處理標記。 – Potatoswatter 2010-03-06 08:46:02
由於註釋在預處理器運行之前(且僅在其之前)被替換爲空格。如果使用預處理器將字符/
和*
粘貼在一起,則會得到/*
,這只是一對夫婦。 編輯:這種濫用##
技術上創建/*
作爲單個令牌,其中有未定義的行爲。你可以粘貼在一起> ## >
或< %:%: :
,雖然你不應該。
請參閱C99的第6.4.6節,瞭解您可以構造什麼標記,以及6.10.3.3是用於連接過程。
從GNU C預處理器文檔:
然而,不一起形成有效令牌兩個令牌不能被粘貼在一起。例如,您不能以任何順序將x與+連接起來。如果您嘗試,預處理器會發出警告併發出兩個令牌。它是否在令牌之間放置空白區域是未定義的。在複雜的宏中找到不必要的'##'使用很常見。如果您收到此警告,則可能只需刪除'##'即可。
在這種情況下,'*'和'/'不構成有效的C或C++標記。所以它們會在它們之間留出空間。
(旁白:你很可能得到C語言編譯錯誤,即使你設法插入「意見」到C預處理器的輸出有不應該有任何意見那裏。)
的錯誤是因爲/*
不是一個有效的標記。
如從CPP doc解釋:
兩個令牌不一起形成一個有效的標記不能粘貼在一起。例如,您不能按任意順序連接
x
和+
。
你可以通過粘貼其他無意義的東西來獲得錯誤,例如/##+
或+##-
。
關於空間,它是故意插入,以避免創建一個評論和其餘的。從GCC source code:
/* Avoid comment headers, since they are still processed in stage 3.
It is simpler to insert a space here, rather than modifying the
lexer to ignore comments in some circumstances. Simply returning
false doesn't work, since we want to clear the PASTE_LEFT flag. */
if ((*plhs)->type == CPP_DIV && rhs->type != CPP_EQ)
*end++ = ' ';
如果你要評論使用預處理器的一些代碼,使用
#if 0
...
#endif
也許你應該添加「abusing_the_c_preprocessor」標籤? ;) – Johan 2010-03-06 08:12:28