2012-04-06 36 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

相关问题