#include预处理程序宏名称空间

时间:2012-09-19 18:02:03

标签: c linux gcc

这个问题是要理解包含头文件的标准行为(不是在我的编译器上实现的行为)。

我有两个具有相同名称的头文件(但内容不同):

1) /user/include/myheader.h  # In standard system folder
2) /private/myheader.h       # In my private folder

假设两个标头包含相同的多个包含预扩展宏

#ifndef MYHEADER
#define MYHEADER
...
#endif

我有C文件/private/test.c,其中包含上述标题:

#include <myheader.h>  // Includes from standard system folder
#include "myheader.h"  // Includes from the folder where test.c is present

两个文件中的内容是否在预处理时进入C文件,因为每个MYHEADER定义都有单独的名称空间?或者由于MYHEADER已在同一名称空间中定义,因此将阻止第二个包含?

4 个答案:

答案 0 :(得分:3)

所有宏只有一个命名空间,所有宏都在同一个命名空间中。将东西放在不同的头文件中对此没有影响 - 它们仍然在同一名称空间中。因此,对于您的示例,第一个标头将定义MYHEADER,这将导致(有效)忽略第二个标头。

答案 1 :(得分:2)

N1570

6.10.3宏替换

...
7紧跟define之后的标识符称为宏名称有一个 宏名称的名称空间。在。之前或之后的任何空格字符 对于任何一种形式的宏,预处理令牌的替换列表都不被视为替换列表的一部分。

强调我的。

如上所述,仅处理第一个myheader.h文件的内容。

答案 2 :(得分:1)

C标准 1 中的预处理器定义没有“名称空间”这样的东西。无论MYHEADER如何定义 2 ,第二个文件的内容都将被忽略。

<小时/> 1 C99标准第6.2.3节定义了四个名称空间 - (1)用于标签,(2)用于struct / union / enum标签,(3)用于每个结构或联合的成员, (4)其他一切。预处理程序定义不属于任何这些名称空间,因为“此处不再考虑宏名称和宏参数,因为在程序转换的语义阶段之前,源文件中出现的任何宏名称都会被预处理标记序列替换这构成了他们的宏观定义。“。

2 就定义MYHEADER而言,您有几个选择:您可以在C文件中,头文件中定义它,或者使用命令行从命令行传递它C编译器的相应选项。

答案 3 :(得分:0)

只使用一个定义,因为#define指令具有全局范围,因此第二个包含将不执行任何操作。

你应该使用MY_PROJECT_MY_HEADER或类似的东西来防止这类问题。