2010-03-06 17 views
7

我想用預處理器評論一行:爲什麼預處理器給出空間?

#define open /##* 

#define close */ 

main() 
{ 
     open commented line close 
} 

當我做$gcc -E filename.c我預計

/* commented line */ 

,但我得到了

/ * commented line */ 

,這樣編譯器顯示的錯誤

爲什麼它給一個不想要的sp王牌?

+4

也許你應該添加「abusing_the_c_preprocessor」標籤? ;) – Johan 2010-03-06 08:12:28

回答

3

預處理器以C編譯器可以理解的形式運行並生成代碼。它只處理你的代碼一次,所以即使你的可能產生/*與你的#define,編譯器會看到/*並給你一個錯誤,因爲它不是有效的C代碼(這是一個預處理指令)。

這似乎不是一件很好的事情。

+0

'#define'是這裏唯一的預處理指令。 '/ *'不是預處理器指令,但不清楚你指的是什麼。 – Potatoswatter 2010-03-06 08:01:19

+1

@Patatoswatter:在將代碼傳遞給編譯器之前,預處理器負責刪除註釋。 – 2010-03-06 08:30:06

+2

根據C99 5.1.1.2/3,註釋是空格,不是預處理標記。 – Potatoswatter 2010-03-06 08:46:02

3

由於註釋在預處理器運行之前(且僅在其之前)被替換爲空格。如果使用預處理器將字符/*粘貼在一起,則會得到/*,這只是一對夫婦。 編輯:這種濫用##技術上創建/*作爲單個令牌,其中有未定義的行爲。你可以粘貼在一起> ## >< %:%: :,雖然你不應該。

請參閱C99的第6.4.6節,瞭解您可以構造什麼標記,以及6.10.3.3是用於連接過程。

6

從GNU C預處理器文檔:

然而,不一起形成有效令牌兩個令牌不能被粘貼在一起。例如,您不能以任何順序將x與+連接起來。如果您嘗試,預處理器會發出警告併發出兩個令牌。它是否在令牌之間放置空白區域是未定義的。在複雜的宏中找到不必要的'##'使用很常見。如果您收到此警告,則可能只需刪除'##'即可。

在這種情況下,'*'和'/'不構成有效的C或C++標記。所以它們會在它們之間留出空間。

(旁白:你很可能得到C語言編譯錯誤,即使你設法插入「意見」到C預處理器的輸出有不應該有任何意見那裏。)

5

的錯誤是因爲/*不是一個有效的標記。

如從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++ = ' '; 
0

如果你要評論使用預處理器的一些代碼,使用

#if 0 
... 
#endif