在 C/C++ 中检测多余的#includes?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/614794/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:16:09  来源:igfitidea点击:

Detecting superfluous #includes in C/C++?

c++crefactoringincludedependencies

提问by shoosh

I often find that the headers section of a file get larger and larger all the time but it never gets smaller. Throughout the life of a source file classes may have moved and been refactored and it's very possible that there are quite a few #includesthat don't need to be there and anymore. Leaving them there only prolong the compile time and adds unnecessary compilation dependencies. Trying to figure out which are still needed can be quite tedious.

我经常发现文件的标题部分一直变得越来越大,但它永远不会变小。在源文件的整个生命周期中,类可能已经移动和重构,并且很可能有很多#includes不需要在那里并且不再存在。将它们留在那里只会延长编译时间并增加不必要的编译依赖项。试图弄清楚哪些仍然需要可能会非常乏味。

Is there some kind of tool that can detect superfluous #include directives and suggest which ones I can safely remove?
Does lint do this maybe?

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

采纳答案by Tzafrir

It's not automatic, but doxygenwill produce dependency diagrams for #includedfiles. You will have to go through them visually, but they can be very useful for getting a picture of what is using what.

这不是自动的,但doxygen会为#included文件生成依赖关系图。您将不得不直观地浏览它们,但它们对于了解正在使用的内容非常有用。

回答by Josh Kelley

Google's cppclean (links to: download, documentation) can find several categories of C++ problems, and it can now find superfluous #includes.

Google 的 cppclean(链接到:下载文档)可以找到几类 C++ 问题,现在它可以找到多余的 #includes。

There's also a Clang-based tool, include-what-you-use, that can do this. include-what-you-use can even suggest forward declarations (so you don't have to #include so much) and optionally clean up your #includes for you.

还有一个基于 Clang 的工具include-what-you-use可以做到这一点。include-what-you-use 甚至可以建议前向声明(因此您不必#include 太多)并可选择为您清理#includes。

Current versions of Eclipse CDTalso have this functionality built in: going under the Source menu and clicking Organize Includes will alphabetize your #include's, add any headers that Eclipse thinks you're using without directly including them, and comments out any headers that it doesn't think you need. This feature isn't 100% reliable, however.

当前版本的Eclipse CDT也内置了此功能:进入 Source 菜单下并单击 Organize Includes 将按字母顺序排列您的 #include,添加 Eclipse 认为您正在使用的任何标头而不直接包含它们,并注释掉它不包含的任何标头认为你不需要。但是,此功能并非 100% 可靠。

回答by Tzafrir

Also check out include-what-you-use, which solves a similar problem.

另请查看include-what-you-use,它解决了类似的问题。

回答by JaredPar

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 anddoes 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 is more of a style checker and certainly won't have this full capability.

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

I think you'll find the only way to detect a superfluous include is to remove, compile and run suites.

我认为您会发现检测多余包含的唯一方法是删除、编译和运行套件。

回答by itsmatt

I thought that PCLintwould do this, but it has been a few years since I've looked at it. You might check it out.

我以为PCLint会这样做,但我已经有几年没有看过它了。你可能会检查一下。

I looked at this blogand the author talked a bit about configuring PCLint to find unused includes. Might be worth a look.

我看了这个博客,作者谈到了一些关于配置 PCLint 以查找未使用的包含的内容。可能值得一看。

回答by Diomidis Spinellis

The CScoutrefactoring browser can detect superfluous include directives in C (unfortunately not C++) code. You can find a description of how it works in thisjournal article.

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

回答by Gilad Naor

You can write a quick script that erases a single #include directive, compiles the projects, and logs the name in the #include and the file it was removed from in the case that no compilation errors occurred.

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

Let it run during the night, and the next day you will have a 100% correct list of include files you can remove.

让它在夜间运行,第二天您将拥有一个 100% 正确的包含文件列表,您可以删除它。

Sometimes brute-force just works :-)

有时蛮力只是有效:-)



edit:and sometimes it doesn't :-). Here's a bit of information from the comments:

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

  1. 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)
  2. 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.
  1. 有时您可以分别删除两个头文件,但不能同时删除。一个解决方案是在运行期间删除头文件而不是将它们带回来。这将找到一个您可以安全删除的文件列表,尽管可能有一个解决方案,其中包含更多该算法找不到的文件要删除。(这是对要删除的包含文件空间的贪婪搜索。它只会找到局部最大值)
  2. 如果根据某些#ifdefs 对某些宏进行了不同的重新定义,则行为可能会发生细微的变化。我认为这些是非常罕见的情况,作为构建一部分的单元测试应该捕捉到这些变化。

回答by Dan

Sorry to (re-)post here, people often don't expand comments.

很抱歉在这里(重新)张贴,人们通常不会扩展评论。

Check my comment to crashmstr, FlexeLint / PC-Lint will do this for you. Informational message 766. Section 11.8.1 of my manual (version 8.0) discusses this.

检查我对 crashmstr 的评论,FlexeLint / PC-Lint 会为你做这件事。信息性消息 766。我的手册(8.0 版)的第 11.8.1 节讨论了这一点。

Also, and this is important, keep iterating until the message goes away. In other words, after removing unused headers, re-run lint, more header files might have become "unneeded" once you remove some unneeded headers. (That might sound silly, read it slowly & parse it, it makes sense.)

此外,这很重要,请继续迭代,直到消息消失。换句话说,在删除未使用的头文件后,重新运行 lint,一旦删除了一些不需要的头文件,更多的头文件可能会变得“不需要”。(这可能听起来很傻,慢慢阅读并解析它,这是有道理的。)

回答by Dan Olson

I've never found a full-fledged tool that accomplishes what you're asking. The closest thing I've used is IncludeManager, which graphs your header inclusion tree so you can visually spot things like headers included in only one file and circular header inclusions.

我从来没有找到一个成熟的工具来完成你的要求。我使用过的最接近的东西是IncludeManager,它绘制了您的标题包含树,以便您可以直观地发现诸如仅包含在一个文件中的标题和圆形标题包含的内容。

回答by PeterSom

If you are using Eclipse CDT you can try http://includator.comwhich is free for beta testers (at the time of this writing) and automatically removes superfluous #includes or adds missing ones. For those users who have FlexeLint or PC-Lint and are using Elicpse CDT, http://linticator.commight be an option (also free for beta test). While it uses Lint's analysis, it provides quick-fixes for automatically remove the superfluous #include statements.

如果您正在使用 Eclipse CDT,您可以尝试http://includator.com,它对 Beta 测试人员免费(在撰写本文时),它会自动删除多余的 #includes 或添加缺少的 #includes。对于那些拥有 FlexeLint 或 PC-Lint 并且正在使用 Elicpse CDT 的用户,http://linticator.com可能是一个选项(也可以免费进行 beta 测试)。虽然它使用 Lint 的分析,但它提供了自动删除多余的 #include 语句的快速修复。