如果我们有两个.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.osub.o,使我认为“两个源文件即两个翻译单元”。

我误解了哪一部分?还是我在哪里犯错?

最佳答案

以下是 C 标准对此的看法:



(来源:C99 标准草案,5.1.1.1 §1)

因此,在您的两种情况下,您都有两个翻译单元。其中之一来自编译器预处理 main.c 以及通过 #include 指令包含的所有内容 - 即 sub.h 以及可能的 <stdio.h> 和其他 header 。第二个来自编译器对 sub.c 做同样的事情。

从第一个示例到第二个示例的不同之处在于,在后者中,您将“不同的翻译单元”明确存储为目标文件。

请注意,没有将一个目标文件与任意数量的翻译单元相关联的规则。 GNU 链接器是 is capable of joining two .o files together 链接器的一个示例。

据我所知,该标准没有指定源文件的扩展名。尽管如此,在实际方面,您可以自由地将 #include 文件 .c 转换为其他文件,或者将整个程序放在 .h 文件中。使用 gcc,您可以使用选项 -x c 强制将 .h 文件视为翻译单元的起点。

这里的区别:



是因为 header 不必是源文件。类似地,<...> 指令中 #include 的内容不需要是有效的文件名。编译器如何准确地使用命名头<...>"..."是实现定义的。

关于C:翻译单元说明,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41927218/

10-16 03:41