在C好奇心中包含头文件

Mir*_*ica 3 c header

我对包含文件及其管理方式有以下好奇心GCC:

假设我有一个源文件foo.c和三个头文件foo.h,foo_cfg.hfoo_int.h.

foo.c中:

#include "foo.h"  
#include "foo_int.h" 
Run Code Online (Sandbox Code Playgroud)

foo.h中:

#include "foo_cfg.h" 
Run Code Online (Sandbox Code Playgroud)

foo_cfg.h中:

/* no inclusions */   
#define FOO BAR
Run Code Online (Sandbox Code Playgroud)

foo_int.h中:

/* no inclusions */ 
#define BAR 0U
Run Code Online (Sandbox Code Playgroud)

我想知道为什么编译成功.foo_cfg.h文件不应该抱怨它不知道BAR符号吗?

此外,我有另一个源文件bar.c,它只包含foo.h文件,仍然有效.

备注:这是我正在处理的一个项目,我正在处理一个复杂的构建环境,其中我没有太多细节.可能是构建环境对此有影响,而不是指定header files?的位置?

可能是这个问题真的很愚蠢,或者我忽略了一些事情,如果是这样我会道歉.

Vla*_*lad 6

没事儿.

你看,预处理器并不关心是否定义了BAR.它只是在后面的源代码中用BAR 替换字符串 FOO,而不是实际关心它是否在该点定义.

接下来,在实际.c文件(编译开始的东西)中包含两个标头,因此编译器会看到两个替换:FOO- > BARBAR- > 0U.所以它成功地应用了它们.

标题永远不会单独编译,它们总是被编译为该标题的.c文件的一部分#include.(预处理器只是假装标头的内容粘贴到所在#include的位置.)因此,对于预处理器,您的文件foo.c如下所示:

/* no inclusions */
#define FOO BAR
/* no inclusions */
#define BAR 0U
/* the rest of the file... */
/* for example: */
unsigned int i = FOO;
Run Code Online (Sandbox Code Playgroud)

预处理后的编译器只看到这个:

/* no inclusions */
/* no inclusions */
/* the rest of the file... */
/* for example: */
unsigned int i = 0U;
Run Code Online (Sandbox Code Playgroud)

(不太确定,也许预处理器也删除了注释.)


编辑:
的确,正如@pmg提到的那样,预处理器用空格替换注释,因此提供给编译器的真实预处理文本只是

_
_
_
_
unsigned int i = 0U;
Run Code Online (Sandbox Code Playgroud)

(这里_表示一个空格)