编译器是否删除未使用的函数,定义,变量,宏,包括等

时间:2013-04-03 08:38:06

标签: c++ visual-c++ gcc compiler-construction

有时在编程时我们定义或声明函数,定义,变量,宏包括和数据结构。但从来没有使用那些。

  1. 编译器(现代编译器能够优化)会自动删除那些未使用的资源吗?
  2. 无论如何都要认出那些?

2 个答案:

答案 0 :(得分:9)

取决于:

编译器将宏转换为程序文本。他们 不代表替换它们的文本以外的任何内容, 并且不要超出编译时间(除非......见下文)。

如果没有局部变量等,可能会将其删除 一个非平凡的构造函数或析构函数。 (你不想要scoped_lock这样的东西只是因为你没有删除 稍后在代码中引用它。)同样适用于变量 和具有内部链接的函数(例如在命名空间定义) 范围与关键字static)。然而,在大多数情况下, 这些对象所需的资源很少,而且节省了 可以忽略不计。

功能有点不同,并且依赖。一个虚函数 如果有任何实例,通常会被视为“已使用” 它的类型,它几乎肯定会存在,即使它 永远不会被称为。

除此之外(这也适用于全局变量):它是 直到链接器。大多数链接器的粒度是对象 编译“翻译单位”产生的文件: 目标文件是或不是您的程序的一部分。如果你 告诉链接器合并目标文件,那么你应该 得到它里面的一切。如果你把目标文件放入 一个(静态)库,并告诉链接器使用它,然后 如果和,链接器会将目标文件合并到您的程序中 只有当它解决了其他未解决的外部问题。但如果它 合并目标文件,它通常将包含所有 它的。 (任何好的库都会将每个非虚函数放入 一个单独的目标文件,所以你得不到你需要的东西。)

在这方面,DLL的行为类似于目标文件(尽管它们是 名称)。如果将目标文件链接到DLL,程序 使用它将获得所有的DLL,或者没有。

最后:虽然不是你的程序的一部分,但目标文件和 最终的可执行文件通常包含符号信息; 最好的系统甚至可以维护有关的信息 宏,以便调试器可以按照您的方式显示事物 写下他们。 (使用宏可以在多大程度上做到这一点是值得商榷的。)

答案 1 :(得分:4)

如果编译器或链接器可以看到没有对C函数或C变量的引用,它们可以(并且通常会)删除那些未使用的东西。

未使用的宏定义根本不会使其成为编译代码。对于typedef等也是如此。

然而,删除在程序的程序集部分中实现的未使用的代码和数据会更加困难。

如果某些引用变量或某些代码将被使用或执行,编译器并不总是显而易见。

所以,是的,这些天,大多数明显未使用的东西都被删除了。