プログラミング、リファクタリング、そしてすべてにおける究極の疑問: No. 40

同カテゴリーの次の記事

プログラミング、リファクタリング、そしてすべてにおける究極の疑問: No. 41

この記事は、インテル® デベロッパー・ゾーンに公開されている「The Ultimate Question of Programming, Refactoring, and Everything」の日本語参考訳です。


40. 静的コード解析を使用する

静的コード解析の開発者が執筆したこのように長い記事で、静的コード解析の使用を推奨しないのは不自然でしょう。ここでは、静的コード解析の使用について述べます。

Haiku* プロジェクト (BeOS* の後継) から抜粋した以下のコードについて考えてみます。このコードにはエラーが含まれています。PVS-Studio アナライザーは、次の診断を出力します。

V501 There are identical sub-expressions to the left and to the right of the ‘<‘ operator: lJack->m_jackType < lJack->m_jackType (V501 ‘<‘ 演算子の左側と右側に同じ部分式があります。)

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)

推奨事項

最初に、役に立たないヒントを紹介しましょう。

  • プログラミング時に細心の注意を払い、コードにエラーが入り込まないようにします (良いアドバイスですが、具体的ではありません)。
  • 適切なコーディング・スタイルを使用します (変数名のエラーの回避に役立つプログラミング・スタイルはありません)。

実際に効果があるのは、次のことです。

  • コードレビュー
  • ユニットテスト (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);

理論的には、ユニットテストは我々のためになるものです。しかし、それは理論上であって、実際には、すべての可能な実行パスをチェックすることは現実的ではありません。また、テスト自体がエラーの原因となること (英語) があります。

静的コード・アナライザーは、単なるプログラムであって、人工知能 (AI) ではありません。エラーをスキップすることもあれば、逆に、実際には正しいコードに対してエラーメッセージを出力することもあります。欠点はありますが、非常に便利なツールです。多くのエラーを早期に検出できます。

静的コード・アナライザーは、コードレビューの簡易版として使用できます。プログラマーに代わって、プログラムがコードを検証して、より詳しい調査が必要なコード領域を提示します。

もちろん、私は開発に携わっている PVS-Studio (英語) コード・アナライザーをお勧めします。しかし、ほかにも無償・有償のさまざまなツールがあります。例えば、無償のオープンソースの Cppcheck (英語) アナライザーを確認してみると良いでしょう。Wikipedia* でも多数のツールが紹介されています: 静的コード解析ツール

使用上の注意:

  • 静的アナライザーは、使い方を誤ると適切な効果が得られません。よくあるミスの 1 つは、「チェック・モード・オプションで最大の情報を取得し、膨大な警告メッセージの中に埋没すること」です。情報量を増やしたい場合は、A (英語) または B (英語) が役立ちます。
  • 静的アナライザーは、ときどき、あるいは問題が起こったときにではなく、定期的に使用すべきです。その理由は、C (英語) と D (英語) で説明されています。

ぜひ、静的コード・アナライザーを使ってみてください。きっと気に入ると思います。静的コード・アナライザーは、非常に優れたサニティー・チェック・ツールです。

最後に、John Carmack 氏の記事「静的コード解析」 (英語) を一読されることを推奨します。

コンパイラーの最適化に関する詳細は、最適化に関する注意事項を参照してください。

関連記事

  • Parallel Universe マガジンParallel Universe マガジン Parallel Universe へようこそ。 米国インテル社が四半期に一度オンラインで公開しているオンラインマガジンです。インテルの技術者によるテクノロジーの解説や、最新ツールの紹介など、並列化に関する記事を毎号掲載しています。第1号からのバックナンバーを PDF 形式で用意しました、ぜひご覧ください。 12 […]
  • 比較関数の罠比較関数の罠 この記事は、インテル® デベロッパー・ゾーンに公開されている「The Evil within the Comparison Functions」の日本語参考訳です。 この記事の PDF […]
  • マルチスレッド開発ガイド: 4.6 インテル® Parallel Composer を利用して並列コードを開発するマルチスレッド開発ガイド: 4.6 インテル® Parallel Composer を利用して並列コードを開発する コードの並列化にはさまざまな手法があります。この記事では、インテル® Parallel Composer で利用可能な手法の概要を説明し、各手法の主な長所を比較します。インテル® Parallel Composer は Windows* 上の C/C++ を使用した開発のみを対象としていますが、これらの手法の多くは Fortran や […]
  • インテル® IPP サンプル – エラーの修正インテル® IPP サンプル – エラーの修正 この記事は、インテル® ソフトウェア・ネットワークに掲載されている「Intel IPP Samples for Windows - error correction」の日本語参考訳です。 この記事は、PVS-Studio を使用することでプログラムがどのように安全になるかを説明した記事の 1 […]
  • 並列プログラミングにおけるロックの効率的な使用並列プログラミングにおけるロックの効率的な使用 この記事は、インテル® ソフトウェア・ネットワークに掲載されている「Using Locks Effectively in Parallel Programming […]