包含和/或链接二进制文件未使用的内容会产生哪些负面后果?
假设我正在构建一个二进制文件,并且包含一堆从未实际使用过的文件,并且后续链接到这些包含文件所描述的库吗? (再次强调,这些库从未被使用过)
除了增加编译时间之外,还有哪些负面后果?
Let's say that I have a binary that I am building, and I include a bunch of files that are never actually used, and do the subsequent linking to the libraries described by those include files? (again, these libraries are never used)
What are the negative consequences of this, beyond increased compile time?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(13)
我能想到的一些是命名空间污染和二进制大小
A few I can think of are namespace pollution and binary size
除了编译时间之外; 复杂性增加、调试时不必要的干扰、维护开销。
除此之外,什么也没有。
In addition to compile time; Increased complexity, needless distraction while debugging, a maintenance overhead.
Apart from that, nothing.
除了 Sasha 列出的之外,还有维护成本。 将来当您选择删除未使用的内容时,您是否能够轻松检测到哪些内容已使用,哪些内容未使用?
In addition to what Sasha lists is maintenance cost. Will you be able to detect easily what is used and what is not used in the future when and if you chose to remove unused stuff?
如果从未使用过这些库,则可执行文件的大小不应增加。
If the libraries are never used, there should be no increase in size for the executable.
根据具体的链接器,您可能还会注意到未使用的库的全局对象仍然被构造。 这意味着内存开销并增加启动成本。
Depending on the exact linker, you might also notice that the global objects of your unused libraries still get constructed. This implies a memory overhead and increases startup costs.
如果您包含但未使用的库不在目标系统上,则即使它们不是必需的,也将无法编译。
If the libraries you're including but not using aren't on the target system, it won't be able to compile even though they aren't necessary.
这里是我的答案有关 C 和静态库的类似问题。 也许它在 C++ 环境中对您也很有用。
Here is my answer for a similar question concerning C and static libraries. Perhaps it is useful to you in the context of C++ as well.
您提到编译时间的增加。 据我了解,这些库是静态链接的,而不是动态链接的。 在这种情况下,这取决于链接器如何处理未使用的函数。 如果忽略它们,您将主要遇到维护问题。 如果包含它们,可执行文件的大小将会增加。 现在,这比它在硬盘上占据的位置更重要。 由于缓存问题,大型可执行文件的运行速度可能会变慢。 如果活动代码和非活动代码在 exe 中相邻,它们将被缓存在一起,从而使缓存实际上更小且效率更低。
VC2005 及更高版本有一个称为 PGO 的优化,它以确保有效缓存常用代码的方式对可执行文件中的代码进行排序。 我不知道 g++ 是否有类似的优化,但值得研究一下。
You mention an increase in the compilation time. From that I understand the libraries are statically linked, and not dynamically. In this case, it depends how the linker handles unused functions. If it ignores them, you will have mostly maintenance problems. If they’ll be included, the executable size will increase. Now, this is more significant than the place it takes on the hard drive. Large executables could run slower due to caching issues. If active code and non-active code are adjacent in the exe, they will be cached together, making the cache effectively smaller and less efficient.
VC2005 and above have an optimization called PGO, which orders the code within the executable in a way that ensures effective caching of code that is often used. I don’t know if g++ has a similar optimization, but it’s worth looking into that.
这里对问题进行了一些汇编,必要时对其进行 wiki 编辑:
主要问题似乎是:命名空间污染
这会给以后的调试、版本控制带来问题,增加以后的维护成本。
至少还会有轻微的二进制膨胀,因为函数/类/命名空间引用将被维护(在符号表中?)。 动态库不应大幅增加二进制文件的大小(但它们会成为二进制文件运行的依赖项?)。 从 GNU C 编译器来看,如果从未在源代码中引用静态链接库,则不应将其包含在最终二进制文件中。 (基于 C 编译器的假设,可能需要澄清/更正)
此外,根据库的性质,可能会实例化全局和静态对象/变量,从而导致增加启动时间和内存开销。
哦,增加了编译/链接时间。
A little compilation here of the issues, wiki-edit it as necessary:
The main problem appears to be: Namespace Pollution
This can cause problems in future debugging, version control, and increased future maintenance cost.
There will also be, at the minimum, minor Binary Bloat, as the function/class/namespace references will be maintained (In the symbol table?). Dynamic libraries should not greatly increase binary size(but they become a dependency for the binary to run?). Judging from the GNU C compiler, statically linked libraries should not be included in final binary if they are never referenced in the source. (Assumption based on the C compiler, may need to clarify/correct)
Also, depending on the nature of your libraries, global and static objects/variables may be instantiated, causing increased startup time and memory overhead.
Oh, and increased compile/linking time.
当我在源树中编辑文件时,我发现它令人沮丧,因为我正在处理的一些符号出现在源文件中(例如函数名称,我刚刚更改了原型 - 或者,可悲的是但更常见的是,只是将原型添加到标头中),因此我需要检查使用是否正确,或者编译器现在告诉我该文件中的使用不正确。 所以,我编辑该文件。 然后我看到一个问题 - 这个文件在做什么? 事实证明,尽管代码在产品中“使用”了,但实际上根本没有被积极使用。
我周一发现出现了这个问题。 包含 10,000 多行代码的文件调用了函数“extern void add_remainder(void);” 参数为 0。所以,我去修复它。 然后我查看了其余的代码...结果发现这是大约 15 年前的开发存根,从未被删除。 事实证明,干净地删除代码涉及到对六个以上文件的细微编辑 - 而且我还没有弄清楚从枚举中间删除枚举常量是否安全。 暂时标记为“未使用/过时 - 可以安全删除吗?”。
过去 15 年里,这部分代码的覆盖率为零——生产、测试……确实,它只是庞大系统的一小部分——从百分比来看,它还不到图表上的 1%。 尽管如此,这仍然是额外的浪费代码。
令人费解。 恼人的。 令人沮丧的是,很常见(今年到目前为止,我已经记录并修复了至少六个类似的错误)。
浪费我的时间和其他开发人员的时间。 多年来,其他人定期编辑该文件,就像我正在做的那样——一项彻底的工作。
I find it frustrating when I edit a file in the source tree because some symbol that I'm working on appears in the source file (e.g. a function name, where I've just changed the prototype - or, sadly but more typically, just added the prototype to a header) so I need to check that the use is correct, or the compiler now tells me the use in that file is incorrect. So, I edit the file. Then I see a problem - what is this file doing? And it turns out that although the code is 'used' in the product, it really isn't actively used at all.
I found an occurrence of this problem on Monday. A file with 10,000+ lines of code invoked a function 'extern void add_remainder(void);' with an argument of 0. So, I went to fix it. Then I looked at the rest of the code...it turned out it was a development stub from about 15 years ago that had never been removed. Cleanly excising the code turned out to involve minor edits to more than half-a-dozen files - and I've not yet worked out whether it is safe to remove the enumeration constant from the middle of an enumeration in case. Temporarily, that is marked 'Unused/Obsolete - can it be removed safely?'.
That chunk of code has had zero cove coverage for the last 15 years - production, test, ... True, it's only a tiny part of a vast system - percentage-wise, it's less than a 1% blip on the chart. Still, it is extra wasted code.
Puzzling. Annoying. Depressingly common (I've logged, and fixed, at least half a dozen similar bugs this year so far).
And a waste of my time - and other developers' time. The file had been edited periodically over the years by other people doing what I was doing - a thorough job.
我在链接仅使用很小一部分的 .lib 文件时从未遇到过任何问题。 只有真正使用的代码才会链接到可执行文件中,并且链接时间并没有明显增加(使用 Visual Studio)。
I have never experienced any problems with linking a .lib file of which only a very small part is used. Only the code that is really used will be linked into the executable, and the linking time did not increase noticeably (with Visual Studio).
如果您链接到二进制文件并在运行时加载它们,它们可能会执行不平凡的初始化,这可以执行任何操作,从分配少量内存到消耗稀缺资源,再到以您意想不到的方式改变模块的状态,以及超过。
你最好扔掉不需要的东西,只是为了消除一堆未知数。
If you link to binaries and they get loaded at runtime, they may perform non-trivial initialization which can do anything from allocate a small amount of memory to consume scarce resources to alter the state of your module in ways you don't expect, and beyond.
You're better off getting rid of stuff you don't need, simply to eliminate a bunch of unknowns.
如果构建树维护得不好,它甚至可能无法编译。 如果您在没有交换空间的嵌入式系统上进行编译。 编译器在尝试编译大量目标文件时可能会耗尽内存。
最近我们工作中就发生了这样的事。
It could perhaps even fail to compile if the build tree isn't well maintained. if your'e compiling on embedded systems without swap space. The compiler can run out of memory while trying to compile a massive object file.
It happened at work to us recently.