有时我看到有人编译这样的C程序:
gcc -o hello hello.c hello.h
据我所知,我们只需要将头文件放入C程序中,如:
#include "somefile"
并编译C程序:gcc -o hello hello.c
.
我们什么时候需要编译头文件或为什么?
AnT*_*AnT 31
首先,一般来说:
如果这些.h
文件确实是典型的C风格的头文件(而不是完全不同的,恰好用.h
扩展命名),那么不,没有理由独立地"编译"这些头文件.头文件旨在包含在实现文件中,而不是作为独立的转换单元提供给编译器.
由于典型的头文件通常只包含可以在每个翻译单元中安全重复的声明,因此完全可以预期"编译"头文件不会产生有害后果.但同时它也无法实现任何有用的功能.
基本上,编译hello.h
为独立的翻译单元,相当于创建dummy.c
仅包含#include "hello.h"
指令的简并文件,并将该dummy.c
文件提供给编译器.它将编译,但它没有任何有意义的目的.
其次,专门针对GCC:
许多编译器会根据文件扩展名对文件进行不同的处理.当GCC .h
作为命令行参数提供给编译器时,GCC对具有扩展名的文件进行特殊处理.GCC不是将其视为常规翻译单元,而是为该文件创建预编译的头.h
文件.
你可以在这里阅读:http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html
因此,这就是您可能会看到.h
文件直接送到GCC的原因.
好的,让我们了解主动代码和被动代码之间的区别。
活动代码是功能,过程,方法的实现,即应编译为可执行机器代码的代码段。我们将其存储在.c文件中,并确保我们需要对其进行编译。
被动代码本身不是在执行,而是需要解释不同的模块如何相互通信。通常,.h文件仅包含原型(函数头),结构。
宏是一个例外,它可以正式包含一个活动的片段,但是您应该了解,它们是在构建(预处理)的早期阶段就使用的,可以通过简单的替换来使用。在编译时,宏已经替换为您的.c文件。
C ++模板是另一个例外,应在.h文件中实现。但是这里的故事类似于宏:它们在早期(实例化)被替换,并且在形式上,彼此实例化是另一种类型。
总而言之,我认为,如果模块正确地构成,则我们绝不应该编译头文件。
小智 5
当我们像这样包含头文件时:#include <header.h> 或 #include "header.h" 那么你的预处理器会将其作为输入并将整个文件包含在源代码中。预处理器用指定文件的内容替换#include 指令。您可以通过 GCC 的 -E 标志来检查这一点,它会生成 .i(信息文件)临时文件,或者可以专门使用 cpp(LINUX) 模块,当我们执行 GCC 时,编译器驱动程序会自动使用该模块。所以它实际上会与你的源代码一起编译,不需要编译它。