问题描述
当我讨论主题.
在某些情况下,对于GCC和VC ++这样的流行编译器,翻译单元中一些未使用的代码是否会链接到最终的可执行代码(当然是在发布模式下)?
例如,假设我们有2个编译单元:
//A.hpp
//Here are declarations of some classes, functions, extern variables etc.
和源文件
//A.cpp
//defination of A.hpp declarations
最后是主
//main.cpp
//including A.hpp library
#include "A.hpp"
//here we will use some stuff from A.hpp library, but not everything
我的问题是.如果在main.cpp中没有使用A.hpp中的所有内容怎么办?链接器会删除所有未使用的代码,还是在某些情况下某些未使用的代码可以与可执行文件链接?
我对G ++和VC ++链接器感兴趣.
我当然是指发布模式.
我开始悬赏这个问题,以获取良好而完整的答案.我期待得到答案,它将解释在哪些情况下g ++和VC ++链接程序链接垃圾邮件以及它们能够从可执行文件中删除哪种代码(不需要的函数,不需要的全局变量,不需要的类定义等),以及他们为什么不能删除某些不需要的东西.
正如其他发布者所指出的那样,链接器通常在构建最终可执行文件之前不会删除无效代码.但是,通常可以使用一些优化设置来强制链接程序进行更多尝试.
对于海湾合作委员会,这是分两个阶段完成的:
-
首先编译数据,但告诉编译器将代码分成翻译单元中的单独部分.这将通过使用以下两个编译器标志针对函数,类和外部变量完成:
-fdata-sections -ffunction-sections
-
使用链接器优化标记将翻译单元链接在一起(这会导致链接器丢弃未引用的部分):
-Wl,-gc-sections
因此,如果您有一个名为test.cpp的文件,该文件中声明了两个函数,但是其中一个未使用,则可以使用以下命令将未使用的一个忽略到gcc(g ++):
gcc -Os -fdata-sections -ffunction-sections test.cpp -o test.o -Wl,--gc-sections
(请注意-Os是一个附加的链接器标志,它告诉GCC优化大小)
我还在某个地方读到,链接静态库是不同的.在这种情况下,该GCC会自动删除未使用的符号.也许另一位张贴者可以确认/否认这一点.
对于MSVC,就像其他人提到的那样,功能级别的链接完成了同样的事情.我相信为此的编译器标志是(将各部分分类):
/Gy
然后是链接器标志(以丢弃未使用的部分):
/OPT:REF
经过进一步研究,我认为有关GCC自动为静态库执行此操作的说法是错误的.
I asked myself the following question, when I was discussing this topic .
Are there cases when some unused code from translation units will link to final executable code (in release mode of course) for popular compilers like GCC and VC++?
For example suppose we have 2 compilation units:
//A.hpp
//Here are declarations of some classes, functions, extern variables etc.
And source file
//A.cpp
//defination of A.hpp declarations
And finally main
//main.cpp
//including A.hpp library
#include "A.hpp"
//here we will use some stuff from A.hpp library, but not everything
My question is. What if in main.cpp not all the stuff from A.hpp is used? Will the linker remove all unused code, or there are some cases, when some unused code can link with executable file?
Edit: I'm interested in G++ and VC++ linkers.
Edit: Of course I mean in release mode.
Edit: I'm starting bounty for this question to get good and full answer. I'm expecting answer, which will explain in which cases g++ and VC++ linkers are linking junk and what kind of code they are able to remove from executable file(unneeded functions, unneeded global variables, unneeded class definitions, etc...) and why aren't they able to remove some kind of unneeded stuff.
As other posters have indicated, the linker typically does not remove dead code before building the final executable. However, there are often Optimization settings you can use to force the linker to try extra hard to do this.
For GCC, this is accomplished in two stages:
First compile the data but tell the compiler to separate the code into separate sections within the translation unit. This will be done for functions, classes, and external variables by using the following two compiler flags:
-fdata-sections -ffunction-sections
Link the translation units together using the linker optimization flag (this causes the linker to discard unreferenced sections):
-Wl,--gc-sections
So if you had one file called test.cpp that had two functions declared in it, but one of them was unused, you could omit the unused one with the following command to gcc(g++):
gcc -Os -fdata-sections -ffunction-sections test.cpp -o test.o -Wl,--gc-sections
(Note that -Os is an additional linker flag that tells GCC to optimize for size)
I have also read somewhere that linking static libraries is different though. That GCC automatically omits unused symbols in this case. Perhaps another poster can confirm/disprove this.
As for MSVC, as others have mentioned, function level linking accomplishes the same thing.I believe the compiler flag for this is (to sort things into sections):
/Gy
And then the linker flag (to discard unused sections):
/OPT:REF
EDIT: After further research, I think that bit about GCC automatically doing this for static libraries is false.
这篇关于来自其他链接单元的垃圾的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!