静态代码分析是检测软件源代码缺陷的过程。静态分析工具对于检测常见的编码错误很有用;使用它们的好处包括:
- 让源代码更易读、更易维护。
- 防止运行时出现意外行为。
- 提升执行性能。
- 让代码更安全。
有许多 C/C++ 静态分析工具可供选择,每种都专注于特定领域,各有优势。例如:
- CppCheck
- Clang Analyzer
- Visual C++ Analyzer
- VERA++
- Goanna
- Viva64
- PCLint
探索这些工具的结果有几种方式:
- XML 格式:这些工具都可以生成 XML 文件,可以用来创建 HTML 报告,或被其他工具消费以探索分析结果。
- HTML 格式:HTML 是生成报告并与团队分享的便捷格式,您还可以使用 XSL 样式表创建自定义报告。
- IDE 插件:几乎所有知名的 IDE 都为这些工具提供了插件,可以直接在源代码中查看违规情况。
代码质量工具的问题之一是,它们往往会用大量并非真正问题的问题——即误报——淹没开发者。当误报出现时,开发者会逐渐学会忽略工具的输出,甚至彻底放弃使用它。
为了更好地探索这些工具的结果,我们需要一种方法,只关注相关的发现,并为开发者提供清晰的结果视图。
CppDepend 和 CQLinq
CppDepend是另一个静态分析工具,可以与其他工具互补。它使用基于 LINQ 的代码查询语言(CQLinq),像查询数据库一样查询代码库。
CppDepend 默认集成了 Cppcheck、Vera++ 和 Clang 分析器,还可以通过其 API 轻松扩展以支持其他静态分析工具。Visual Studio Analyzer 插件的源代码是开放的,展示了如何集成其他工具。
让我们以 Clang 源代码为例,看看如何使用 CppDepend 探索这些工具的结果。
获取所有问题:
检索所有问题的查询非常简单。然而,正如您所见,这并不是很有用——事实上,处理一个包含 331417 个问题的结果是一项挑战。

为了更好地处理这些工具的结果,我们可以对它们进行过滤,只关注我们想要的内容。
按工具查询
我们可以修改第一个查询,为相关工具添加条件。

报告最频繁的问题
了解哪些问题被这些工具最频繁地报告,是很有意思的。
最常见的是 Vera++ 报告的风格问题;如果它们在您的情况下不相关,我们可以将它们从查询中排除。
问题最多的类
了解哪些类包含大量违规是非常有意思的。

前面的查询很有意思,但它并不能准确告诉我们哪些类的质量问题最严重。另一个值得考虑的有用度量是代码行数(NBLinesOfCode)。我们可以修改前面的查询,计算问题数量与 NBLinesOfCode 之间的比率。

被广泛使用且存在问题的方法
当静态分析工具报告问题时,了解哪些问题应该优先处理是很有用的,尤其是当它们涉及 Bug 时。一个 Bug 可能存在于某个特定的方法中,但有意思的问题是:有多少方法受到这个 Bug 的影响。被广泛使用的方法会被更多代码调用,最好尽快解决它们的问题。

使用 CQLinq,我们可以将所有这些工具的结果以及 CppDepend 的结果组合起来,创建更精细的查询,并将这些检查加入构建流程。
问题趋势
软件项目中出现问题并不罕见;任何项目都可能有需要解决的问题。然而,我们应该监控项目的质量趋势。事实上,如果问题数量随着项目的变更和演进而增长,这是一个不好的信号。CppDepend 提供了趋势监控(Trend Monitoring)功能来创建趋势图。
趋势图是基于分析过程中随时间记录的度量值构建的。默认提供 50 多个趋势度量,创建您自己的趋势度量也很容易。
通过这张趋势图,我们可以监控 Cppcheck 问题随时间的演变:

将静态分析工具的结果集成到 HTML 报告中
CppDepend 允许在 HTML 报告中附加额外的报告章节,列出一些 CQLinq 查询。
在 CQLinq 查询资源管理器(CQLinq Query Explorer)面板中,被加入报告的 CQLinq 分组会用橙色矩形框标出。

在 HTML 报告中,可以从菜单访问这些附加章节:

将静态分析工具的结果集成到构建流程中
CppDepend 引入了关键 CQLinq 规则(Critical CQLinq Rule)的概念。关键规则提供了一种定义高优先级规则的方式,这些规则绝不能被违反。借助关键规则,可以在发生关键规则违规时中断构建流程。
关键规则就是勾选了Critical Rule(关键规则)标志的 CQLinq 规则:

在构建流程中,当关键规则被违反时,CppDepend.Console.exe会返回非零退出码。可以利用这一行为,在关键规则被违反时中断构建流程。
我们可以轻松定义一条 Cppcheck 关键规则,在发现特定类型的 Cppcheck 问题时中断构建。
结论
CppDepend 对其他静态分析工具持开放态度,您还可以轻松集成自己的自定义工具。这样,您就能利用 CppDepend 的所有功能,更好地探索受支持的 C/C++ 静态分析工具的结果。
