我正在研究Visual Studio 2008中的一个大型C++项目,并且有很多文件带有不必要的#include
指令.有时#include
s只是工件,一切都会被删除,但是在其他情况下,类可以向前声明,#include可以移动到.cpp
文件中.是否有任何好的工具可以检测这两种情况?
虽然它不会显示不需要的包含文件,但Visual Studio有一个设置/showIncludes
(右键单击.cpp
文件Properties->C/C++->Advanced
),它将在编译时输出所有包含文件的树.这有助于识别不需要包含的文件.
您还可以查看pimpl习惯用法,以便减少头文件依赖性,从而更容易看到可以删除的内容.
PC Lint对此非常有效,它也为您找到各种其他愚蠢的问题.它具有可用于在Visual Studio中创建外部工具的命令行选项,但我发现Visual Lint插件更易于使用.即使是免费版的Visual Lint也有帮助.但给PC-Lint一个机会.配置它以便它不会给你太多的警告需要一点时间,但你会惊讶于它出现了什么.
有一个新的基于Clang的工具,包括你的用途,旨在实现这一目标.
!!免责声明!我从事商业静态分析工具(不是PC Lint).!!免责声明!
简单的非解析方法有几个问题:
1)过载集:
重载函数可能具有来自不同文件的声明.可能是删除一个头文件会导致选择不同的重载而不是编译错误!结果将是语义的静默变化,之后可能很难跟踪.
2)模板专业化:
与重载示例类似,如果您对模板具有部分或显式特化,则希望在使用模板时它们都可见.可能是主模板的特化是在不同的头文件中.使用特化删除标头不会导致编译错误,但如果已选择该特化,则可能导致未定义的行为.(参见:C++函数模板特化的可见性)
正如'msalters'所指出的那样,对代码进行全面分析还可以分析类的使用情况.通过检查文件的特定路径如何使用类,有可能可以完全删除类的定义(以及它的所有依赖性),或者至少移动到更接近包含主要源的级别树.
我不知道有任何这样的工具,我曾考虑过写一个这样的工具,但事实证明这是一个难以解决的问题.
说你的源文件包含啊和bh; 啊包含#define USE_FEATURE_X
和bh使用#ifdef USE_FEATURE_X
.如果#include "a.h"
被注释掉,您的文件仍然可以编译,但可能不会按预期执行.以编程方式检测这一点并非易事.
无论使用什么工具,您都需要了解构建环境.如果啊看起来像:
#if defined( WINNT ) #define USE_FEATURE_X #endif
然后USE_FEATURE_X
仅定义if WINNT
定义,因此该工具需要知道编译器本身生成的指令以及在编译命令中而不是在头文件中指定的指令.
像Timmermans一样,我对此并不熟悉任何工具.但我知道编写Perl(或Python)脚本的程序员尝试一次注释掉每个include行,然后编译每个文件.
看来现在Eric Raymond 有了这个工具.
谷歌的cpplint.py有一个"包含你使用的"规则(以及其他许多规则),但据我所知,没有" 仅包括你使用的内容".即便如此,它也很有用.
如果您对这个主题感兴趣,可能需要查看Lakos的大规模C++软件设计.这有点过时了,但是会遇到许多"物理设计"问题,例如找到需要包含的标题的绝对最小值.我还没有真正看到其他任何地方讨论过这种事情.