我对包含文件及其管理方式有以下好奇心GCC:
假设我有一个源文件foo.c和三个头文件foo.h,foo_cfg.h和foo_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?的位置?
可能是这个问题真的很愚蠢,或者我忽略了一些事情,如果是这样我会道歉.
没事儿.
你看,预处理器并不关心是否定义了BAR.它只是在后面的源代码中用BAR 替换字符串 FOO,而不是实际关心它是否在该点定义.
接下来,在实际.c文件(编译开始的东西)中包含两个标头,因此编译器会看到两个替换:FOO- > BAR和BAR- > 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)
(这里_表示一个空格)