[英]Include header file in C curiosity
我对包含文件及其管理方式(使用GCC
)有以下好奇心:
假设我有一个源文件foo.c和三个头文件foo.h , foo_cfg.h和foo_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
- > 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;
预处理后的编译器只看到这个:
/* 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.