包含和/或链接二进制文件未使用的内容会带来什么负面后果?

时间:2009-04-15 14:27:21

标签: c++ linux linker g++ ld

假设我有一个我正在构建的二进制文件,并且我包含了一堆从未实际使用过的文件,并且后续链接到这些包含文件所描述的库? (再次,这些库从未使用过)

除了增加编译时间之外,这有什么负面影响?

13 个答案:

答案 0 :(得分:8)

我能想到的一些是命名空间污染二进制文件大小

答案 1 :(得分:5)

除了编译时间;增加了复杂性,在调试时不必要的分心,维护开销。

除此之外,没什么。

答案 2 :(得分:4)

除了Sasha列出的维护费用。如果您选择删除未使用的东西,您是否能够轻松检测到将来使用的和未使用的内容?

答案 3 :(得分:4)

如果从未使用过库,则可执行文件的大小不应增加。

答案 4 :(得分:3)

根据确切的链接器,您可能还会注意到仍未构建未使用的库的全局对象。这意味着内存开销并增加启动成本。

答案 5 :(得分:1)

如果您包含但未使用的库不在目标系统上,即使它们不是必需的,它也无法编译。

答案 6 :(得分:1)

Here是关于C和静态库的类似问题的答案。也许它在C ++的上下文中也很有用。

答案 7 :(得分:1)

你提到了编译时间的增加。据我所知,这些库是静态链接的,而不是动态链接的。在这种情况下,它取决于链接器如何处理未使用的函数。如果忽略它们,则主要是维护问题。如果它们将被包含,则可执行文件大小将增加。现在,这比它在硬盘驱动器上的位置更重要。由于缓存问题,大型可执行文件可能会运行得更慢。如果活动代码和非活动代码在exe中相邻,它们将被缓存在一起,使缓存实际上更小,效率更低。

VC2005及更高版本有一个名为PGO的优化,它以确保有效缓存经常使用的代码的方式对可执行文件中的代码进行排序。我不知道g ++是否有类似的优化,但值得研究。

答案 8 :(得分:1)

这里有一些关于问题的汇编,wiki-根据需要编辑它:

主要问题似乎是:命名空间污染 这可能会在将来的调试,版本控制和未来维护成本增加方面造成问题。

至少还会有次要的 Binary Bloat ,因为将维护函数/类/命名空间引用(在符号表中?)。动态库不应该大大增加二进制大小(但它们成为二进制运行的依赖项?)。从GNU C编译器来看,如果从未在源代码中引用静态链接库,则不应将其包含在最终二进制文件中。 (基于C编译器的假设,可能需要澄清/更正)

此外,根据库的性质,可能会实例化全局和静态对象/变量,从而导致增加启动时间和内存开销

哦,并且增加了编译/链接时间。

答案 9 :(得分:1)

当我在源代码树中编辑文件时,我感到很沮丧,因为我正在处理的某个符号出现在源文件中(例如,函数名称,我刚刚更改了原型 - 或者,遗憾的是更多通常,只是将原型添加到标题中)所以我需要检查使用是否正确,或者编译器现在告诉我该文件中的使用是不正确的。所以,我编辑文件。然后我看到一个问题 - 这个文件在做什么?事实证明,尽管代码在产品中被“使用”,但它实际上并没有被主动使用。

周一我发现了这个问题。包含10,000多行代码的文件调用了一个函数'extern void add_remainder(void);'参数为0.所以,我去解决它。然后我查看了剩下的代码......结果发现它是大约15年前的一个开发存根,从未删除过。干净地删除代码结果是对超过六个文件进行了少量编辑 - 我还没有确定从枚举中间删除枚举常量是否安全。暂时标记为“未使用/已过时 - 是否可以安全删除?”。

在过去的15年里,这一大块代码已经实现零覆盖 - 生产,测试......真的,它只是庞大系统的一小部分 - 百分比方面,它不到1%的昙花一现图表。不过,这是额外浪费的代码。

令人费解。烦人。令人沮丧的是(到目前为止,我已经登录并修复了至少6个类似的错误)。

浪费我的时间 - 和其他开发人员的时间。多年来,其他人一直在做我正在做的事情 - 这是一份彻底的工作。

答案 10 :(得分:0)

我从未遇到任何链接.lib文件的问题,该文件只使用了很小的部分。只有真正使用的代码才会链接到可执行文件中,并且链接时间没有明显增加(使用Visual Studio)。

答案 11 :(得分:0)

如果链接到二进制文件并且它们在运行时加载,它们可能会执行非平凡的初始化,这可以做任何事情,从分配少量内存到消耗稀缺资源来改变模块的状态期待,甚至超越。

你最好摆脱不需要的东西,只是为了消除一堆未知数。

答案 12 :(得分:0)

如果构建树没有得到很好的维护,它甚至可能无法编译。如果您在没有交换空间的情况下编译嵌入式系统。在尝试编译大量目标文件时,编译器可能会耗尽内存。

最近发生在我们身上的工作。