未使用的function是否被优化了?

一个相当简单的问题…这些日子的编译器往往做了大量的优化。 他们是否也从最终输出中删除未使用的function?

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

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

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

不知道其他编译器。

一般来说,答案是:

是的:用于未使用的staticfunction。

否:用于未使用的全球可用function。

编译器不知道其他编译单元是否引用它。 另外,大多数对象模块types不允许在编译后删除函数,也不提供链接器判断是否存在内部引用的方法。 (链接器可以告诉你是否有外部链接器。)有些链接器可以做到这一点,但是很多事情都是这样做的。

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

许多编译器都这么做,但这取决于具体的实现。 debugging版本通常会包含所有的函数,以允许在debugging器中调用或检查它们。 许多embedded式系统编译器,由于我不完全理解(*)的原因,如果包含任何一个对象文件,它将包含所有这些函数,但会完全忽略任何根本不用的对象文件。

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

(*)我知道它使得编译和链接变得更容易,但是今天的计算机应该可以运行比过去几十年来实践更复杂的编译和链接algorithm。 如果没有别的,在预编译/链接阶段可以使用两遍预编译/预链接/编译/链接方法产生所使用事物的列表,然后在“真实”编译/链接阶段省略那些不是。

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

有关gcc优化的更多信息可以在这里find

很多时候,是的。 它通常被称为链接器剥离。

当谈到MS时, 链接器会在链接阶段处理这个问题,编译器可能会警告您未使用的静态函数(文件范围)。 如果您希望链接器删除未使用的函数,请使用/ OPT:REF选项:

所有你需要的是这个__declspec(selectany)variables或函数

在这里检查http://msdn.microsoft.com/en-us/library/5tkz6s71%28v=vs.71%29.aspx

它将删除函数或variables,如果它没有在代码中引用

这一切都取决于编译器及其设置(内置“debugging”configuration的代码一般不会优化),以及代码本身和行星alignment。

基本的事情是:你不应该担心那些东西。 相信你的编译器。