2012-04-06 40 views
2

我在編寫代碼時發現了一些有趣的東西。我在我的代碼中定義了一個宏,並意外地使用關鍵字int作爲該宏的參數的變量名稱。代碼工作得很好,但我對此感到有點驚訝。我讀過C中的關鍵字是保留字,不能用作變量名。可能宏參數的名稱是關鍵字嗎?

這是我的代碼:

#include <stdio.h> 

#define PRINT(int) printf("%d",int) 

int main() 
{ 
    int x=2; 
    PRINT(x); 
    return 0; 
} 

任何人都可以解釋我爲什麼會工作的罰款?關鍵字是否被保留並且不能用作C中的變量名,或者這是C中宏的一個例外嗎?

回答

6

在此背景下,int不是一個變量(更正確的:參數)的名字,因爲當然PRINT的也不是一個功能 - 這是一個預處理宏。

無論您作爲宏定義的一部分編寫什麼,只會被預處理器查看。當編譯器看到處理後的源文件時,名稱上沒有任何內容。

這與函數的形式參數發生的情況類似:編譯器可以看到這些名稱,但是在完成源代碼之後,它們的蹤跡仍然保留在編譯代碼中(因此您需要在代碼中加載調試符號調試器「獲取此信息」)。

+0

這意味着我可以使用任何關鍵字宏,它會正常工作,對不對?這個東西只對C中的宏有效嗎? – 2012-04-06 11:47:14

+0

@dark_shadow:預處理器不知道C,所以就它而言*有*沒有關鍵字(所以是的,你可以使用任何東西)。它在C和C++中有效。 – Jon 2012-04-06 11:48:40

+0

感謝Jon清除懷疑。 – 2012-04-06 11:53:14

2

在預處理階段,關鍵字不存在,只是被看作普通的標識符。

4

在C編譯器看到它之前,#define被預處理器所取代。編譯器本身看到的是:

這是有效的C代碼。使用關鍵字作爲變量名會產生錯誤:

int main() 
{ 
int float=2; 
printf("%s",float); 
return 0; 
} 

這不會編譯。

1

C標準章節5.1.1.2定義了C翻譯的九個階段。預處理階段是4號;關鍵字僅在階段7中被識別;在此階段之前,所有關鍵字都被認爲是正常的預處理令牌。進一步的細節見the standard

keyword: one of auto break case [...]

The above tokens (case sensitive) are reserved (in translation phases 7 and 8) for use as keywords, and shall not be used otherwise.

+0

但是你鏈接到一個C++標準。 – cnicutar 2012-04-06 11:48:12

+0

@cnicutar你是對的!我修復了鏈接並更新了節號。 – dasblinkenlight 2012-04-06 11:55:06

+0

另外一個小的補充,C++標準,但不包含C標準,明確地不允許在包含標準頭文件時使用名稱_lexically與keywords_相同的名稱來定義宏。 – AProgrammer 2012-04-06 12:04:47

相關問題