c++ - (boost like) header only libraries 如何影响编译大小?

标签 c++ boost compilation header-files precompile

当我在两个翻译单元中包含 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/

相关文章:

c++ - 为什么 ->[] 在 C++ 中不是运算符? (取消引用数组指针的下标运算符)

c++ - ReadFile 使用 NamedPipe block 虽然使用重叠

c# - 编译错误 CS0029 无法将类型 'ComboBox.ObjectCollection' 隐式转换为 'CheckedListBox.ObjectCollection'

c++ - Visual Studio 2012 编译时间慢

compilation - Chapel如何处理 "includes"

c++ - 生产者/消费者,消费者线程从未执行过

C++ Win32,用位图显示窗口的最简单方法

带有 boost 的 python 的 C++ 扩展不起作用

c++ - 如果在 WinXP 上的调试版本中使用 boost (C++) 库,则无法执行程序

c++ - 是否可以检查 boost::lockfree::queue 是否已满?