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