我经常发现文件的头部分总是变得越来越大,但它从来没有变小过。在源文件的整个生命周期中,类可能会被移动和重构,并且很可能有相当多的#include不需要存在。保留它们只会延长编译时间,并增加不必要的编译依赖关系。试图找出哪些仍然需要是相当乏味的。

是否有某种工具可以检测多余的#include指令,并建议哪些我可以安全地删除? 棉绒会这样吗?


当前回答

很抱歉(再次)在这里发帖,人们通常不扩展评论。

检查我对crashmstr的评论,FlexeLint / PC-Lint会为你做这件事。信息信息766号。我的手册(8.0版)的11.8.1节讨论了这个问题。

另外,这一点很重要,不断迭代,直到消息消失。换句话说,在删除了不需要的头文件后,重新运行lint,一旦删除了一些不需要的头文件,更多的头文件可能已经成为“不需要的”。(这可能听起来很傻,慢慢读并分析它,这是有道理的。)

其他回答

本文解释了一种使用Doxygen解析来删除#include的技术。这只是一个perl脚本,所以它很容易使用。

CLion是JetBrains开发的C/ c++ IDE,可以即时检测冗余内容。这些在编辑器中是灰色的,但也有一些函数可以优化当前文件或整个项目中的包含。

我发现你需要为这个功能付费;当第一次加载时,CLion需要一段时间来扫描和分析您的项目。

也许有点晚了,但我曾经找到一个WebKit perl脚本,它做的正是你想要的。我相信它需要一些调整(我不太精通perl),但它应该能做到:

http://trac.webkit.org/browser/branches/old/safari-3-2-branch/WebKitTools/Scripts/find-extra-includes

(这是一个旧的分支,因为trunk不再有文件了)

CScout重构浏览器可以检测C(不幸的是不是c++)代码中多余的include指令。你可以在这篇期刊文章中找到它如何工作的描述。

我尝试过使用Flexelint (PC-Lint的unix版本),结果有些复杂。这可能是因为我正在处理一个非常庞大且复杂的代码库。我建议仔细检查报告为未使用的每个文件。

主要的担忧是假阳性。同一报头的多个包含被报告为不需要的报头。这是很糟糕的,因为Flexelint没有告诉你头文件被包含在哪一行或者它之前被包含在哪里。

自动化工具可能会出错的一种方式是:

在A.hpp:

class A { 
  // ...
};

在B.hpp:

#include "A.hpp

class B {
    public:
        A foo;
};

在C.cpp:

#include "C.hpp"  

#include "B.hpp"  // <-- Unneeded, but lint reports it as needed
#include "A.hpp"  // <-- Needed, but lint reports it as unneeded

如果你盲目地跟随Flexelint的消息,你会把#include依赖项搞砸。有更多的病理情况,但基本上你需要自己检查标题,以获得最好的结果。

我强烈推荐这篇来自博客Games的关于物理结构和c++的文章。他们推荐了一个全面的方法来清理#include混乱:

的指导方针 以下是从Lakos的书中提炼出来的一组指导原则,可以最大限度地减少文件之间的物理依赖关系。我已经使用它们很多年了,我对效果一直很满意。 每个cpp文件首先包含它自己的头文件。(剪) 头文件必须包含解析它所需的所有头文件。(剪) 头文件应该有最少的头文件来解析它。(剪)