【发布时间】:2015-06-27 04:02:26
【问题描述】:
我现在正在使用编译器,我想确保问题不是对头文件的基本误解。如果我包含一个头文件,并且该头文件包含在其中(如<stdbool.h> 或<stdio.h> 等),那么依赖的C 文件应该没有任何问题,对吧?根据我的理解,预处理器应该在我调用我的 makefile 时相应地插入汇编代码。我弄错了吗?
重申:
假设我有一个
main.c和prototype.h。prototype.h包含了我所有常用的库和其他内容。我还有几个其他的 C 文件(例如
secondary.c和tertiary.c),它们都需要常用的库,并且可能需要也可能不需要一些原型,并且还有自己的头文件。
我需要做的就是在每个 C 文件中包含 prototype.h,对吗?
另外,在这种情况下,如果我在makefile 中使用gcc 的-c 标志制作.o 文件,我是否需要更新makefile 目标中的依赖关系?
当我开始的时候我以为我已经掌握了这个,但现在我完全糊涂了。
【问题讨论】:
-
错了。每个源文件都必须包含编译包含在该源文件中的指令所需的头文件。 (源文件当然可以有一个包含必要头文件的头文件——但你不能依赖代码中某处的其他文件也包含该文件的事实——编译器不能那样工作)每个源文件被认为是一个编译单元,它必须具有直接可用的所需头文件。
-
是的,在另一个头文件中包含一个头文件仍然有效,只要它直接或间接地包含在需要它的源文件中……但最好将头文件直接包含在无论如何,需要它们的文件,如果没有其他原因,只是为了清晰。
-
参见Should I use
#includein headers?,答案是“是”。您应该区分库(通常存储在特殊文件中的目标代码)和标头(绝对不是目标代码)。标头声明了库提供的设施,但这与包含库不同。如果tertiary.c需要prototypes.h,请包含它。如果它还需要tertiary.h并且prototypes.h未包含它,则在tertiary.c中的prototypes.h之前包含tertiary.h。标头应该是自包含的和幂等的。 -
@DavidC.Rankin:“必须”?不。例如,如果我有一个调用
printf的源文件,则该源文件包含"foo.h"是完全合法的,而<stdio.h>又包含<stdio.h>。我同意最佳实践是直接包含任何需要的标题;关键是编译器不会强制执行这种做法。 -
是的,我就是这么说的。如果头文件包含编译单元中所需的头文件,那很好。但是您不能依赖其他编译单元可能会为您包含它的事实。