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

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


当前回答

您可以编写一个快速脚本,删除单个#include指令,编译项目,并在没有发生编译错误的情况下记录#include中的名称和它被删除的文件。

让它在晚上运行,第二天你就会有一个100%正确的可以删除的包含文件列表。

有时候蛮力很管用:-)


编辑:有时它不会:-)。下面是一些来自评论的信息:

Sometimes you can remove two header files separately, but not both together. A solution is to remove the header files during the run and not bring them back. This will find a list of files you can safely remove, although there might a solution with more files to remove which this algorithm won't find. (it's a greedy search over the space of include files to remove. It will only find a local maximum) There may be subtle changes in behavior if you have some macros redefined differently depending on some #ifdefs. I think these are very rare cases, and the Unit Tests which are part of the build should catch these changes.

其他回答

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

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

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

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

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

您可以编写一个快速脚本,删除单个#include指令,编译项目,并在没有发生编译错误的情况下记录#include中的名称和它被删除的文件。

让它在晚上运行,第二天你就会有一个100%正确的可以删除的包含文件列表。

有时候蛮力很管用:-)


编辑:有时它不会:-)。下面是一些来自评论的信息:

Sometimes you can remove two header files separately, but not both together. A solution is to remove the header files during the run and not bring them back. This will find a list of files you can safely remove, although there might a solution with more files to remove which this algorithm won't find. (it's a greedy search over the space of include files to remove. It will only find a local maximum) There may be subtle changes in behavior if you have some macros redefined differently depending on some #ifdefs. I think these are very rare cases, and the Unit Tests which are part of the build should catch these changes.

The problem with detecting superfluous includes is that it can't be just a type dependency checker. A superfluous include is a file which provides nothing of value to the compilation and does not alter another item which other files depend. There are many ways a header file can alter a compile, say by defining a constant, redefining and/or deleting a used macro, adding a namespace which alters the lookup of a name some way down the line. In order to detect items like the namespace you need much more than a preprocessor, you in fact almost need a full compiler.

Lint更多的是一个样式检查器,当然不会有这个完整的功能。

我想你会发现检测多余include的唯一方法是删除、编译和运行套件。

我从来没有找到一个成熟的工具来完成你的要求。我使用过的最接近的工具是IncludeManager,它将头包含树图形化,以便您可以直观地发现只包含在一个文件中的头和循环头包含之类的内容。