将C++代码分成多个翻译单元是否会增加可执行文件的开销?

5
我有一些代码在静态库中被多个项目共享。即使使用函数级链接,输出的目标文件代码量仍然比我想要的多——可以参考这个问题
显然,减少链接到最终可执行文件中的目标代码量的最直接解决方案是将翻译单元拆分,以便获得更多的.obj文件,每个文件包含更少的目标代码。我甚至可以走极端——将每个函数放入单独的翻译单元中。
假设我不关心由于有十倍的.cpp文件而引起的混乱,也不关心可能的链接时间增长。
这样分割成许多目标文件会对可执行文件大小产生额外开销吗?只是因为链接了十倍的.obj文件(但总体上它们具有完全相同的函数和变量)而使可执行文件变得更大吗?

你的函数有多大?在极端情况下,由于调用者保存寄存器等原因,函数调用可能比内联函数更大。 - Steve Jessop
我希望你已经尝试过“strip”命令和编译优化选项。例如,参见http://wiki.wxwidgets.org/Reducing_Executable_Size。 - amit kumar
@zebrabox:Win32 Visual C++ 9. 真的很重要吗? - sharptooth
@sharptooth。死代码剥离可以显著减小程序的总体大小,但在链接器方面差异很大,例如,普通的gcc会进行死代码剥离,但通常不会消除虚函数调用。不确定VC++ 9会怎么做。 - zebrabox
虽然我意识到这并没有真正回答你的问题!我确实听说过这种技术被使用,例如 PlayStation 1 的 C 运行时库每个翻译单元只有一个函数,但我自己从未尝试过。 - zebrabox
3个回答

3

可能会影响最终EXE大小的因素(不是详尽列表):

  • 你是静态链接还是动态链接库(动态链接更小,因为库代码不在EXE中)
  • 使用许多模板类(例如vector<A>, vector<B>, vector<C>)可能会导致代码膨胀,因为每个具有不同类型的vector实例都会单独编译
  • 编译器设置,例如优化、大小与速度、内联(大量内联可能使代码更大),如果支持则进行整个程序优化
  • 链接器设置,例如如果支持,则删除冗余或相同的数据。可以帮助减小大小。

简而言之,将代码分成更多的翻译单位可能没有影响-相同的代码,只是重新组织。如果您的编译器不考虑整个程序优化,甚至可能会使情况变得更糟,因为每个翻译单位都包含关于程序的较少信息。


2

我认为,使用现代编译器输出文件大小的优势将会非常微小。据我所知,编译器仅使用在您的代码中引用的那些函数。其他函数和符号将从输出文件中跳过。


请参见此问题链接到的另一个问题 - 没有适当拆分源代码可能会导致数百个未使用的全局变量与可执行文件相关联。 - sharptooth

1

不。我认为你需要的是将静态库重新编译为共享库,或者使用类似strip -g -s -R .comment这样的工具来删除未使用的代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接