如果我们有两个 .c 文件和一个 .h 文件:main.c sub.c sub.h
,其中
main.c
#include "sub.h"
...
sub.c
#include "sub.h"
...
我们可以用 i) 编译程序
gcc -o a.out main.c sub.c
或 ii)
gcc -c main.c
gcc -c sub.c
gcc -o a.out main.o sub.o
在这种情况下,预处理器是否输出一个或两个翻译单元?
我很困惑,因为:main.c
包含sub.h
,这意味着预处理器将输出一个编译单元。另一方面,在创建可执行文件之前创建了两个目标文件,main.o
和 sub.o
,这让我认为“两个源文件因此两个翻译单位。”
我误解了哪一部分?或者我在哪里犯了错误?
最佳答案
将可执行文件的生成视为两个步骤:首先,将每个翻译单元编译为目标文件;让我们称之为编译器。其次,目标文件链接在一起成为一个可执行程序;我们称其为链接器。
“翻译单元”是第一步的事情。翻译单元是编译开始的每个文件(即传递给编译器的文件)。在大多数 IDE 中,有一些规则声明扩展名为 .c
或 .cpp
的每个文件都作为输入传递给编译器,而其他文件则不然。因此,扩展名为 .h
、.hpp
、.txt
的文件通常不会直接传递给编译器。
在您的示例中,main.c
和 sub.c
可能是翻译单元,而 sub.h
本身不是翻译单元(它仅“包含”在其他翻译单元中,并在其编译过程中考虑)。
所以你得到两个目标文件,每个翻译单元一个。然后链接器会考虑这两个目标文件。
请注意,即使是 .h
文件也可能包含完整的程序;但除非您将环境配置为该 .h
文件是自行编译的,否则它不会生成目标文件。
关于C:翻译单位说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41927218/