可能重复:
C++ 中的“翻译单元”是什么
常说C/C++声明的静态变量跨编译单元不可见?这是否意味着每个 .c 或 .cpp 文件都是一个单独的编译单元? .h 文件和 .h 文件中声明的静态变量怎么样? .h 文件是否也被视为一个单独的编译单元?
头文件没有单独的生命,只有它们的内容是
#included
成.c或.cpp文件。但是由于 #include
是由预处理器处理的,编译器不知道不同的头文件;它只将生成的代码列表视为输入。这就是所谓的编译单元:一个源文件,其所有#include
指令都被相关头文件的内容和所有其他处理过的预处理器语句(如#define
,#ifdef
等)替换。
C 和 C++ 编译(通常)分为三个独立的步骤:
只要有
#include
或宏,预处理器就会用实际值扩展该表达式。在 #include
的情况下,整行都替换为 .h 文件内容。
实际的编译器(通常)不知道任何头文件,它将编译单元视为一个大的 .c 或 .cpp 文件。
“通常”部分来自这样一个事实,即某些编译器通过将预编译的标头存储在某种缓存中来优化标头包含,但效果是一样的。
编译器只处理源文件,通常扩展名为.c或.cpp。编译器并不真正关心包含的文件:就通常实现的编译器而言,每个 .c/.cpp 文件都会重新处理,无论读取什么 .h 文件(由预处理器提供)。
这就是我们谈论“编译单元”的原因:一次性编译的东西,其结果随后可能会链接在一起成为可执行文件。