【问题标题】:Does C++ compiler optimize out #includes that are not used?C++ 编译器是否优化了未使用的#includes?
【发布时间】:2012-12-09 03:44:56
【问题描述】:

在构建不断增长的类/函数库时,我经常看到一种“伞形”头文件,它#include 项目的所有常见头文件。例如:

dsp.h
#include "file1.h"
#include "file2.h"
...
#include "filex.h"

有时我可能需要所有东西,但有时可能只需要选择一些功能/选项。例如,如果#include dsp.h,但不使用 file2.h 中的任何内容,编译器是否知道?是否有可能在构建中对其进行优化?

否则,我的解决方案是将可选代码包装在预处理器指令中,然后定义我需要的内容。也许这是一个更安全、更有效的解决方案?

【问题讨论】:

    标签: c++ optimization include c-preprocessor


    【解决方案1】:

    你说的是代码优化还是构建时间优化?

    不必要的、未使用的标头不会改变正在生成的代码,所以这里不存在优化问题。

    但是,它会增加构建时间。这没有通过构建工具进行优化。如果您希望优化构建时间,请查看 John Lakos 所著的Large Scale C++ Software Design一书。

    【讨论】:

    • 我说的是代码优化,而不是构建时间。基本上,如果包含一个没有使用的头文件,它仍然会包含在构建的可执行文件中,从而增加代码大小吗?
    • @user93353 如果不知道头文件的代码,您将无法做出决定。
    • @NikosC。您是否有一个未使用标头但仍会增加代码大小的示例?
    • @user93353 一个典型的类头。类需要的所有数据/代码显然都保存到二进制文件中。一个简单的测试是用一个空的 main() 函数编译一个简单的程序。在我的系统上,创建的目标文件是 752 字节大。仅添加这个包括:#include <iostream> 将生成一个 992 字节大的目标文件。所有调试符号都被剥离。大多数头文件都会有这个效果。
    • @NikosC。我在 Visual Studio 2010 上试过这个。我的 exe 大小在一个只有一个空的 main 的程序和一个还有一个 #include <iostream> 的程序之间没有变化。它保持不变。我认为链接器应该足够聪明,可以丢弃所有未使用的东西。当然,标准对此只字未提,但任何复杂的链接器都应该能够做到这一点。 iostream 也可能是一种特殊情况 - 可能是您的工具仅在包含至少一个标准库标头时才会拉入标准库。
    【解决方案2】:

    预处理器不做任何优化。它对代码的语义一无所知,因此无法判断您是否使用了头文件中的任何内容。所以不,#include 语句没有被优化出来。

    【讨论】:

      【解决方案3】:

      由于预处理器是独立于 C++ 编译器的程序(和语言),因此预处理器无法知道使用了什么。所以编译器将接收头文件中的所有内容。

      【讨论】:

        【解决方案4】:

        包含文件被读取,并在编译器真正开始生成代码之前插入部分源代码。

        是的。作为一般规则,程序未引用的内容不会放入最终的可执行文件中。可以将其视为一种优化。具体细节会因编译器和链接器而异。

        【讨论】:

          猜你喜欢
          • 2011-03-18
          • 2014-04-18
          • 1970-01-01
          • 2015-06-16
          • 1970-01-01
          • 2018-07-24
          • 2014-05-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多