1

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

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

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

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

4

4 回答 4

3

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

于 2012-09-19T18:06:03.037 回答
2

N1570

6.10.3 宏替换

...
7 紧随其后的标识符define称为宏名称宏名称有一个名称空间。预处理标记替换列表之前或之后的任何空白字符均不被视为任一宏形式的替换列表的一部分。

强调我的。

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

于 2012-09-19T18:29:25.703 回答
1

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


1 C99 标准第 6.2.3 节定义了四个名称空间 - (1) 用于标签,(2) 用于结构/联合/枚举标签,(3) 用于每个结构或联合的成员,以及 (4) 用于其他所有内容. 预处理器定义不属于这些名称空间中的任何一个,因为“这里没有进一步考虑宏名称和宏参数,因为在程序翻译的语义阶段之前,源文件中出现的任何宏名称都被预处理标记序列替换这构成了它们的宏定义。”。

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

于 2012-09-19T18:05:09.513 回答
0

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

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

于 2012-09-19T18:17:32.933 回答