【问题标题】:C includes of includes in headersC 头文件中包含的包含
【发布时间】:2015-06-27 04:02:26
【问题描述】:

我现在正在使用编译器,我想确保问题不是对头文件的基本误解。如果我包含一个头文件,并且该头文件包含在其中(如<stdbool.h><stdio.h> 等),那么依赖的C 文件应该没有任何问题,对吧?根据我的理解,预处理器应该在我调用我的 makefile 时相应地插入汇编代码。我弄错了吗?

重申:

  • 假设我有一个main.cprototype.h

  • prototype.h 包含了我所有常用的库和其他内容。

  • 我还有几个其他的 C 文件(例如secondary.ctertiary.c),它们都需要常用的库,并且可能需要也可能不需要一些原型,并且还有自己的头文件。

我需要做的就是在每个 C 文件中包含 prototype.h,对吗?

另外,在这种情况下,如果我在makefile 中使用gcc-c 标志制作.o 文件,我是否需要更新makefile 目标中的依赖关系?

当我开始的时候我以为我已经掌握了这个,但现在我完全糊涂了。

【问题讨论】:

  • 错了。每个源文件都必须包含编译包含在该源文件中的指令所需的头文件。 (源文件当然可以有一个包含必要头文件的头文件——但你不能依赖代码中某处的其他文件也包含该文件的事实——编译器不能那样工作)每个源文件被认为是一个编译单元,它必须具有直接可用的所需头文件。
  • 是的,在另一个头文件中包含一个头文件仍然有效,只要它直接或间接地包含在需要它的源文件中……但最好将头文件直接包含在无论如何,需要它们的文件,如果没有其他原因,只是为了清晰。
  • 参见Should I use #include in headers?,答案是“是”。您应该区分库(通常存储在特殊文件中的目标代码)和标头(绝对不是目标代码)。标头声明了库提供的设施,但这与包含库不同。如果tertiary.c 需要prototypes.h,请包含它。如果它还需要tertiary.h 并且prototypes.h 未包含它,则在tertiary.c 中的prototypes.h 之前包含tertiary.h。标头应该是自包含的和幂等的。
  • @DavidC.Rankin:“必须”?不。例如,如果我有一个调用printf 的源文件,则该源文件包含"foo.h" 是完全合法的,而<stdio.h> 又包含<stdio.h>。我同意最佳实践是直接包含任何需要的标题;关键是编译器不会强制执行这种做法。
  • 是的,我就是这么说的。如果头文件包含编译单元中所需的头文件,那很好。但是您不能依赖其他编译单元可能会为您包含它的事实。

标签: c makefile gnu


【解决方案1】:

这是有多个答案的问题。

在简单的情况下,只有在 .c 文件中使用时才包含标题。标头是编译的依赖项,因此对于 Make,您只需将其放在使用这些文件的 .c 文件所在的同一存储桶中。

对于加快编译的大型项目,您可以使用所谓的“预编译头文件”。您必须在每个源文件中包含相同的头文件,编译器只会处理该头文件一次。当标头很复杂(例如 boost 库)时,这非常有用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多