当我在两个翻译单元中包含 boost 库 hpp header 时,boost 代码是否编译两次(与传统的预编译库相比,二进制大小是两倍?)?
最佳答案
您问了两个不同的问题:
boost 代码是否编译两次?是的,它确实。最终结果是编译时间可能会稍长一些,因为编译器必须消化每个编译单元的所有 header 。
二进制大小加倍?不,它可能不会,但这将归结为您选择的优化标志。在单元 A 中实例化的模板理论上将与单元 B 中实例化的模板共享相同的实现代码,完全相同类型参数。
它是否真的共享相同的代码将取决于您的优化标志是否允许内联模板实现。如果您允许内联并且编译器选择这样做,那么您的二进制文件大小将会增加,因为编译器将模板实现与您的代码内联以实现您规定的优化目标。
只有二进制的库不可能进行内联,因此这就是使用仅 header 库时二进制文件大小可能会增加的原因之一。
这是一个示例,展示了在未启用内联时 gcc 如何共享模板实现:
a.cpp
#include <vector>
void test1() {
std::vector<int> myvec;
myvec.push_back(1);
}
b.cpp
#include <vector>
void test2() {
std::vector<int> myvec;
myvec.push_back(1);
}
m.cpp
extern void test1(),test2();
main() {
test1();
test2();
}
编译
g++ -g -O0 -fno-inline -c m.cpp
g++ -g -O0 -fno-inline -c a.cpp
g++ -g -O0 -fno-inline -c b.cpp
g++ -o a.out a.o b.o m.o
objdump -S a.out |less
objdump分析
void test1() {
// [snip]
myvec.push_back(1);
// [snip]
4008a0: e8 d1 00 00 00 callq 400976 <_ZNSt6vectorIiSaIiEE9push_backERKi>
void test2() {
// [snip]
myvec.push_back(1);
// [snip]
401548: e8 29 f4 ff ff callq 400976 <_ZNSt6vectorIiSaIiEE9push_backERKi>
请注意如何使用相同的 push_back
实现(位置 400976),即使它被编译成完全独立的编译单元。
关于c++ - (boost like) header only libraries 如何影响编译大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27618646/