如果从未调用函数,编译器在创建程序时是否省略它?

时间:2013-04-08 13:54:00

标签: c++ performance optimization

当编译器运行其优化时,是否省略了从未调用过的函数?我记得读过一些不包含不必要文件的内容,因为它会在程序中造成不必要的膨胀,所以我只能从该语句中假设它在编译时确实包含了从未使用的所述函数,但我认为没有任何逻辑编译器不删除它们的原因,我认为大多数现代编译器可能会删除额外的未使用函数。

3 个答案:

答案 0 :(得分:6)

一般来说,答案是'不'。但是某些编译器会在某些特定情况下消除某些功能。并且链接器也不会包含源文件中静态链接库的函数,其中不需要该文件中的函数。

通常被消除的一个常见情况是永远不会被调用的静态函数,从不采用谁的地址。另一个是静态函数,它在所有被调用的地方内联,并且从不采用谁的地址。

这完全取决于编译器。

但是,一般来说,这很难做到,因为编译器通常没有整个程序的视图来构建一个全面的调用图。并且链接器不够智能。

此外,某些文件可能最终成为库的一部分。并且库的整个目的是拥有一堆未从库本身调用的代码。编译器无法在编译时确定给定的代码段是否进入库。所以,这意味着对于具有“外部链接”的函数,如果不使用它们,则链接器可以忽略它们。

答案 1 :(得分:4)

它在很大程度上取决于编译器,但是,在某些设置中,编译器可以完全消除未调用的函数。编译器必须确保函数确实从未被调用过。

特别是标记为static的功能可以很容易地消除 - 只需查看相同的翻译单元即可。如果可以从另一个翻译单元调用函数,则会变得更难。 Visual C ++有一个特殊的设置,称为“函数级链接”和链接器设置for removing unreferenced functions。当这两个一起使用时,未完成的功能将被完全消除。

答案 2 :(得分:3)

可以做。 C ++编译器仅在 as-if 规则下运行。只要生成的程序符合标准规定,编译器就可以做任何它想做的事情。

  

符合实现需要模拟(仅)抽象机器的可观察行为

如果永远不会调用该函数,那么编译器当然可以摆脱它,但它完全取决于编译器是否存在。但是,C ++的编译模型要求翻译单元是单独编译的。编译器通常不可能或很难知道该函数永远不会从任何其他翻译单元调用。