翻译《有关编程、重构及其他的终极问题?》——40.开始使用静态代码分析

翻译《有关编程、重构及其他的终极问题?》——40.开始使用静态代码分析

标签(空格分隔):翻译 技术 C/C++
作者:Andrey Karpov
翻译者:顾笑群 - Rafael Gu
最后更新:2018年09月28日


40.开始使用静态代码分析

阅读一位静态代码分析器的开发者写的一大段文字,却不知道如何使用静态代码分析,这是非常奇怪的。所以这次我们就来说说如何使用静态代码分析。

下面的代码摘自Haiku项目(从BeOS项目继承而来)。这段代码包含的错误被PVS-Studio分析器诊断为:There are identical sub-expressions to the left and to the right of the ‘<’ operator: lJack->m_jackType < lJack->m_jackType(译者注:大意为“<”操作符两边的变量是一样的)。

int compareTypeAndID(....)
{
  ....
  if (lJack && rJack)
  {
    if (lJack->m_jackType < lJack->m_jackType)
    {
      return -1;
    }
    ....
}

解释

这只是一个平常的打字错误,在表达式的右边,理应是rJack,却被写成了lJack。

这种打字错误的确比较简单,但实际产生这种情况的原因却很复杂,这可能牵扯到编程风格等一系列问题,但即使知道什么问题导致,也无助于解决。大家就是这么眼睁睁的犯下类似错误,你却无能为力。

很重要的是,我们要意识到,这种问题不是特定的人或者特定的项目才有。毫无疑问,所有人都会犯类似错误,即使在正规项目总的专家们也会犯。我说这些是有证据的,你可以看到类似最简单的A == A这种打字错误,都可以在如下项目中被发现:Notepad++,WinMerge,Chromium,Qt,Clang,OpenCV,TortoiseSVN,LibreOffice,CoreCLR,Unreal Engine 4等。

因此这类问题是真实存在的,不光是在实验室中的学生项目中。当一些人告诉我说那些有经验的程序员不会犯下这类错误时,我就给他们发送了这个链接。

正确的代码

if (lJack->m_jackType < rJack->m_jackType)

建议

首先,让我们说一些无用的敲门:

  • 编程时要很小心,不要让错误偷溜进你的代码(说的好听,但毫无用处)
  • 使用好的代码风格(事实上,不存在一种编程风格可以避免变量名的拼写错误)

那么,那些是真正有用的呢:

  • 代码复查(译者注:就是我们一般直接使用英文说的code review)
  • 单元测试(TDD)(译者注:TDD就是敏捷开发中的测试驱动)
  • 静态代码分析

我不得不说,以上每种策略都有它的长处和短处,这就是为何最好、最有效的办法就是把他们一起使用。

代码复查能帮助我们找出大量的不同错误,并且,能帮助我们提高代码的可阅读性。但不幸的是,这种策略的代价时非常昂贵的,而且比较无聊,最后也不能给出一个完全有效复查的保证。比如,下面的代码打字错误就非常难以被发现:

qreal l = (orig->x1 - orig->x2)*(orig->x1 - orig->x2) +
          (orig->y1 - orig->y2)*(orig->y1 - orig->y1) *
          (orig->x3 - orig->x4)*(orig->x3 - orig->x4) +
          (orig->y3 - orig->y4)*(orig->y3 - orig->y4);

理论上,单元测试可以拯救我们。但只在理论上有这个可能。因为实际上,检查所有的执行路径是不现实的;除此之外,一个测试本身也有可能包含错误:)

静态代码分析器也会有问题,而且也不是智能化的。一个分析器可能忽略一些错误,另一方面,还有可能显示一些实际上正确的错误。但除了这些问题外,静态代码分析器其实能算得上是一种真正有用的工具,它可以在初期就可以发现大量的错误。

一个静态代码分析器可以被用来做性价比高的代码复查。使用程序而非程序员来做代码复查,然后更全面的建议检查特定的代码片段。

当然,我很愿意建议大家使用我们开发的PVS-Studio代码分析器,但这并非世界上唯一一款代码分析器,还有其他很多免费或付费的同类工具。比如你可以尝试使用一下免费、开源的分析器Cppcheck。你可以在Wikipedia上找到大量的同类工具:静态代码分析工具列表。

注意:

  • 错误的使用一个静态代码分析器可能反而会让你头疼。比如一种典型的错误就是“尽量多的得到检查结果的警告消息”。这是我经常收到的建议,所以就得到了一个很多很多的错误警告列表,对于这种情况,这两篇文章A和B会有帮助。
  • 一个静态代码分析器应该被当成基本工具使用,而不仅仅是每次使用一下,或者当项目情况越来越糟糕了才使用。相关的的解释可以看C和D这两篇文章。

真的,尝试用用静态代码分析工具吧,你会喜欢上他们的,他们是非常好的清洁工具。

最后,我很愿意推荐大家读一下John Carmack的文章:静态代码分析。

你可能感兴趣的:(技术)