繁体   English   中英

在C好奇心中包含头文件

[英]Include header file in C curiosity

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

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

foo.c中

#include "foo.h"  
#include "foo_int.h" 

foo.h中

#include "foo_cfg.h" 

foo_cfg.h中

/* no inclusions */   
#define FOO BAR

foo_int.h中

/* no inclusions */ 
#define BAR 0U

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

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

备注:这是我正在处理的一个项目,我正在处理一个复杂的构建环境,其中我没有太多细节。 除了指定header files的位置之外,构建环境是否会对此产生影响?

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

没事儿。

你看,预处理器并不关心是否定义了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;

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

/* no inclusions */
/* no inclusions */
/* the rest of the file... */
/* for example: */
unsigned int i = 0U;

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


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

_
_
_
_
unsigned int i = 0U;

(这里_表示空格)

为了扩展弗拉德的答案:

预处理器宏在使用时会扩展,而不是在定义时扩展。
所以当你写#define FOO BAR ,它所做的就是记住FOO = BAR。
当你写#define BAR 0U ,它会记住BAR = 0U。

现在,当在代码中看到FOO时,它被替换为BAR ,它立即被替换为0U
#define FOO#define BAR在源中出现的顺序并不重要。 重要的是,当第一次看到FOO时,两个定义都已经完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM