包含源文件场景下如何判定最终翻译单元的构成与数量?
翻译单元数量判定及构成说明
首先明确核心规则:翻译单元的数量仅和你交给编译器做独立编译的.c/.cpp源文件数量直接相关,和代码内部#include引入的文件类型、引入逻辑没有直接关系。#include本质是预处理阶段的纯文本替换操作:预处理时会把你引入的文件内容原封不动插入到#include指令所在的位置,替换掉该指令,预处理完成后的完整代码就构成了当前输入源文件对应的翻译单元。
场景1:某.cpp文件内引入另一.cpp文件
举个实际例子:你有a.cpp、b.cpp两个源文件,其中a.cpp的代码里写了#include "b.cpp"。
- 如果你仅将
a.cpp作为唯一输入交给编译器编译,不单独编译b.cpp:
最终只会生成1个翻译单元,构成为:a.cpp自身代码 +a.cpp引入的所有头文件代码 + 插入到#include "b.cpp"位置的完整b.cpp代码。 - 如果你同时将
a.cpp、b.cpp都作为独立输入交给编译器编译:
最终会生成2个翻译单元:- 第一个对应
a.cpp:a.cpp自身代码 +a.cpp引入的所有头文件代码 + 插入的完整b.cpp代码 - 第二个对应
b.cpp:b.cpp自身代码 +b.cpp引入的所有头文件代码
这种情况大概率会触发链接期重定义错误:b.cpp里的非静态全局函数、变量会在两个翻译单元中各存在一份定义,链接器无法决议。
- 第一个对应
场景2:.cpp文件被引入到会被其他.cpp包含的.h文件中
举个实际例子:你有x.cpp、y.cpp两个待编译的源文件,二者都引入了common.h,而common.h中写了#include "z.cpp"。
如果你将x.cpp和y.cpp都作为独立输入交给编译器编译,最终会生成2个翻译单元:
- 第一个对应
x.cpp:x.cpp自身代码 +x.cpp引入的所有头文件代码(包含已经插入了完整z.cpp代码的common.h内容) - 第二个对应
y.cpp:y.cpp自身代码 +y.cpp引入的所有头文件代码(同样包含已经插入了完整z.cpp代码的common.h内容)
这种场景几乎必然触发链接期重定义错误,除非z.cpp里的所有全局定义都是static或者inline修饰的。
补充说明
不要被.h/.cpp的后缀迷惑,预处理阶段不会校验引入文件的后缀合法性,只要内容是合法的C/C++代码,就算你引入.txt/.md文件都可以正常完成预处理,完全不会改变翻译单元的计数规则。
内容的提问来源于stack exchange,提问作者Physician
相关产品推荐
相关产品推荐

