2011-02-14 74 views
15

可能重复:
What is a “translation unit” in C++如何在C++中定义编译单元?

人们常常说,静态变量声明在C/C++不能跨编译单元可见?这是否意味着每个.c或.cpp文件都是独立的编译单元?那么.h文件和.h文件中声明的静态变量怎么样? .h文件是否也被视为单独的编译单元?

+0

可能的重复:http://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c – Flexo 2011-02-14 12:44:46

+6

从技术上来说是重复的,但假设你知道“编译单元”是与“翻译单位”相同。 – MSalters 2011-02-14 12:55:26

回答

27

头文件没有单独的生命,只有它们的内容是#included到.c或.cpp文件中。但由于#include是由预处理器处理的,因此编译器不了解不同的头文件;它只将结果代码列表看作输入。这就是所谓的编译单元:一个源文件,其所有#include指令被替换为相关头文件的内容。

4

编译器只处理源文件,通常使用扩展名.c或.cpp。编译器并不关心包含的文件:只要通常实现编译器,就会重新处理每个.c/.cpp文件,无论读取什么.h文件(由预处理器提供)。

这就是为什么我们谈论'编译单元':一次编译的内容,其结果可能随后被链接到可执行文件中。

8

C和C++汇编(通常)分割在三个独立的步骤:

  • 预处理,涉及宏观和#包括扩展。
  • 编译,将源代码转换为二进制代码并生成中间对象文件。
  • 将单个ELF或EXE文件中的目标文件链接起来。

无论哪里有#include或宏,预处理器都会将该表达式与实际值进行扩展。在#include的情况下,整行被替换为.h文件内容。

实际的编译器(通常)不知道任何头文件,它将编译单元视为一个大的.c或.cpp文件。

“通常”部分来自于某些编译器通过在某种缓存中存储预编译头来优化头包含的事实,但效果是相同的。