未使用的功能会被优化吗?

Pau*_*nta 49 c c++ compiler-construction

一个相当简单的问题......这些天的编译器倾向于进行大量的优化.它们是否也从最终输出中删除未使用的函数?

sha*_*oth 27

这取决于编译器.Visual C++ 9可以做到这一点 - static在编译阶段删除未使用的函数(甚至还有C4505警告),可以在链接阶段删除未使用的具有外部链接的函数,具体取决于链接器设置.


rub*_*nvb 21

如果您使用/Gy和链接编译,MSVC(Visual Studio编译器/链接器)可以执行此操作/OPT:REF.

如果您使用-ffunction-sections -fdata-sections和链接编译,GCC/binutils可以执行此操作--gc-sections.

不知道其他编译器.


Dig*_*oss 16

作为一般规则,答案是:

是:对于未使用的static功能.

否:   用于未使用的全局可用功能.

编译器不知道某个其他编译单元是否引用它.此外,大多数对象模块类型不允许在编译后删除函数,也不提供链接器告知是否存在内部引用的方法.(链接器可以判断是否存在外部链接.)一些链接器可以做到这一点,但很多事情都可以解决这个问题.

当然,任何链接器都不会不必要地加载其自己模块中的函数,除非它是共享库的一部分.(因为它可能在将来在运行时被引用,显然.)


小智 5

使用gcc如果你打开optmizations它可以删除未使用的函数和死代码.

有关gcc优化的更多信息,请点击此处


sup*_*cat 5

许多编译器都这样做,但它取决于具体的实现.调试版本通常包含所有函数,以允许在调试器中调用或检查它们.由于我不完全理解(*)的原因,许多嵌入式系统编译器将包含目标文件中的所有函数(如果它们包含任何函数),但将完全省略任何根本未使用的目标文件.

请注意,在支持Reflection的语言(例如Java,C#,vb.net等)中,在给定函数名称的情况下,即使代码中不存在引用,也可以在运行时创建对它的引用.例如,例程可以接受来自控制台的字符串,以某种方式对其进行处理,并通过该名称生成对函数的调用.编译器或链接器无法知道可能生成的名称,因此无法知道代码中可以安全地省略哪些函数.但是,在C或C++中不存在这样的困难,因为代码没有定义的方法来创建对函数,变量或常量的引用,而代码中不存在显式引用.一些实现可以安排事情,以便连续存储连续声明的常量或变量,并且因此可以通过向先前声明的一个添加偏移来创建对稍后声明的常量的引用,但是这样的技巧的行为是明确的不受C或C++标准的保证.

(*)据我所知,它使编译和链接更容易,但今天的计算机运行更复杂的编译和链接算法应该没有过去几十年的实际情况.如果没有别的,两个预编译/预链接/编译/链接方法可以在预编译/链接阶段产生一个使用的东西列表,然后在"真正的"编译/链接阶段省略那些不是.