C++ 未使用的功能是否得到优化?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6215782/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Do unused functions get optimized out?
提问by Paul Manta
A fairly simple question... Compilers these days tend to do a significant amount of optimizations. Do they also remove unused functions from the final output?
一个相当简单的问题......如今的编译器往往会进行大量优化。他们是否也从最终输出中删除了未使用的函数?
采纳答案by sharptooth
It depends on the compiler. Visual C++ 9 can do that - unused static
functions are removed at compilation phase (there's even a C4505 warningfor that), unused functions with external linkage can be removed at link phase depending on linker settings.
这取决于编译器。Visual C++ 9 可以做到这一点——未使用的static
函数在编译阶段被删除(甚至有一个C4505 警告),可以在链接阶段删除带有外部链接的未使用函数,具体取决于链接器设置。
回答by rubenvb
MSVC (the Visual Studio compiler/linker) can do this if you compile with /Gy
and link with /OPT:REF
.
GCC/binutils can do this if you compile with -ffunction-sections -fdata-sections
and link with --gc-sections
.
如果您-ffunction-sections -fdata-sections
使用--gc-sections
.
Don't know about other compilers.
不知道其他编译器。
回答by DigitalRoss
As a general rule, the answer is:
一般来说,答案是:
Yes:for unused static
functions.
是:用于未使用的static
功能。
No: for unused globally available functions.
否: 用于未使用的全局可用函数。
The compiler doesn't know if some other compilation unit references it. Also, most object module types do not allow functions to be removed after compilation and also do not provide a way for the linker to tell if there exist internal references. (The linker can tell if there are externalones.) Some linkers can do it but many things work against this.
编译器不知道其他编译单元是否引用了它。此外,大多数目标模块类型不允许在编译后删除函数,也不提供链接器判断是否存在内部引用的方法。(链接器可以判断是否有外部链接器。)有些链接器可以做到,但很多事情都与此相反。
Of course, a function in its own module won't be loaded unnecessarily by any linker, unless it is part of a shared library. (Because it might be referenced in the future at runtime, obviously.)
当然,任何链接器都不会不必要地加载自己模块中的函数,除非它是共享库的一部分。(因为很明显,将来可能会在运行时引用它。)
回答by supercat
Many compilers do, but it depends on the particular implementation. Debug builds will often include all functions, to allow them to be invoked or examined from within the debugger. Many embedded systems compilers, for reasons I don't totally understand(*), will include all of the functions in an object file if they include any, but will omit entirely any object files that aren't used at all.
许多编译器都这样做,但这取决于特定的实现。调试构建通常包括所有函数,以允许从调试器中调用或检查它们。许多嵌入式系统编译器,出于我不完全理解的原因(*),如果它们包含任何函数,则会将所有函数包含在一个目标文件中,但会完全省略任何根本不使用的目标文件。
Note that in languages which support Reflection (e.g. Java, C#, vb.net, etc.) it's possible, given the name of a function, to create a reference to it at runtime even if no references exist in the code. For example, a routine could accept a string from the console, munge it in some fashion, and generate a call to a function by that name. There would be no way for a compiler or linker to know what names might be so generated, and thus no way to know what functions may be safely omitted from the code. No such difficulty exists in C or C++, however, since there is no defined way for code to create a reference to a function, variable, or constant without an explicit reference existing in the code. Some implementations may arrange things so that consecutively-declared constants or variables will be stored consecutively, and one might thus create a reference to a later-declared one by adding an offset to an earlier-declared one, but the behavior of such tricks is explicitly not guaranteed by the C or C++ standards.
请注意,在支持反射的语言(例如 Java、C#、vb.net 等)中,即使代码中不存在引用,也可以在给定函数名称的情况下在运行时创建对它的引用。例如,例程可以从控制台接受一个字符串,以某种方式对其进行处理,然后生成对该名称的函数的调用。编译器或链接器无法知道可能会生成哪些名称,因此无法知道可以从代码中安全地省略哪些函数。但是,在 C 或 C++ 中不存在这样的困难,因为在代码中没有显式引用存在的情况下,没有定义的方法可以让代码创建对函数、变量或常量的引用。一些实现可能会安排一些事情,以便连续声明的常量或变量将被连续存储,
(*)I understand that it makes compiling and linking easier, but today's computers should have no trouble running more sophisticated compiling and linking algorithms than would have been practical in decades past. If nothing else, a two-pass pre-compile/pre-link/compile/link method could on the pre-compile/link phase produce a list of things that are used, and then on the "real" compile/link phase omit those that are not.
(*)我知道它使编译和链接更容易,但是今天的计算机应该可以轻松运行比过去几十年更复杂的编译和链接算法。如果不出意外,两遍预编译/预链接/编译/链接方法可以在预编译/链接阶段生成使用的东西的列表,然后在“真正的”编译/链接阶段省略那些不是。
回答by rsachetto
回答by Goz
Quite a lot of the time, yes. Its often called linker stripping.
很多时候,是的。它通常称为链接器剥离。
回答by ralphtheninja
When it comes to MS it's the linkerthat takes care of this during link phase and the compiler might warn you about unused static functions (file scope). If you want the linker to remove unused functions you use the /OPT:REFoption:
当涉及到 MS 时,链接器会在链接阶段处理这个问题,编译器可能会警告您有关未使用的静态函数(文件范围)。如果您希望链接器删除未使用的函数,请使用/OPT:REF选项:
回答by handcoded
Under MSVC and with global functions or variable you can use __declspec( selectany ).
在 MSVC 和全局函数或变量下,您可以使用__declspec( selectany )。
It will remove the function or variable if it has not being referenced in the code if the linker option /OPT:REF (Optimizations) is selected.
如果选择了链接器选项 /OPT:REF(优化),它将删除代码中未引用的函数或变量。
回答by Etienne de Martel
It all depends on the compiler and its settings (code built in "debug" configurations generally isn't optimized), along with the code itself and the planet alignment.
这完全取决于编译器及其设置(“调试”配置中内置的代码通常未优化),以及代码本身和行星对齐。
The underlying thing is: you should not worry about that stuff. Trust your compiler.
根本的事情是:你不应该担心那些东西。相信你的编译器。