ブログ 約4分

C++のコードスメルを追跡する:データベースアプローチ

Share this article
C++のコードスメルを追跡する:データベースアプローチ

静的解析は、バグを直接見つけるだけでなく、コードの可読性や保守性を損なう可能性のある、バグを招きやすい状況を見つけることでもあります。静的解析では、コードの他の多くの特性も調べられます:

  • コードメトリクス:たとえば、ループ、if、else、switch、case文が多すぎるメソッドは理解しにくくなり、その結果保守も困難になります。これらを循環的複雑度というコードメトリクスで数えることは、メソッドがいつ複雑すぎる状態になるかを評価する優れた方法です。
  • 依存関係:プログラムのクラスが複雑に絡み合っている場合、コードへの変更がもたらす影響は予測不能になります。静的解析は、クラスやコンポーネントが絡み合っている状況を評価するのに役立ちます。
  • 不変性:複数のスレッドから同時に使用される型は、不変であるべきです。そうでなければ、状態の読み書きアクセスを複雑なロック戦略で保護しなければならず、最終的に保守不能になります。静的解析は、特定のクラスが不変のままであることを確認できます。
  • デッドコード:デッドコードとは、実行時に呼び出されなくなったため、安全に削除できるコードです。削除 できます だけでなく、 削除しなければなりません 。この余分なコードはプログラムに不要な複雑さを追加するからです。静的解析では、プログラム内のほとんどのデッドコード(ただし全部ではない)を検出できます。
  • APIの破壊的変更:クライアントにAPIを提供している場合、公開メンバーを気づかずに削除してクライアントのコードを壊してしまうのは非常に容易です。静的解析では、プログラムの2つの状態を比較し、この落とし穴について警告できます。
  • APIの使用:一部のAPIは慎重に使用されることを意図しています。たとえば、破棄可能なフィールドを保持するクラスは、一般的にそれ自体も破棄可能である必要があります。ただし、破棄可能なフィールドの有効期間がクラスインスタンスの有効期間と一致しない場合は除きます。その場合は設計上の問題の兆候です。

コードスメルも、バグを招きやすい状況と見なすことができます。以下はWikipediaによる定義です:

In computer programming, コードスメル, (or 悪臭) is any symptom in the source code of a program that possibly indicates a deeper problem. According to Martin Fowler, "a code smell is a surface indication that usually corresponds to a deeper problem in the system". Another way to look at smells is with respect to principles and quality: "smells are certain structures in the code that indicate violation of fundamental design principles and negatively impact design quality". Code smells are usually not bugs—they are not technically incorrect and do not currently prevent the program from functioning. Instead, they indicate weaknesses in design that may be slowing down development or increasing the risk of bugs or failures in the future. Bad code smells can be an indicator of factors that contribute to technical debt. Robert C. Martin calls a list of code smells a "value system" for software craftsmanship.

Cppcheck、Clang-Tidy、Visual Studioアナライザーなど、C++コードベースのバグを検出できる便利なツールは数多くあります。では、コードスメルの検出はどうでしょうか?

静的解析ツールの開発者は、どの状況をバグと見なすかを決定できますが、コードスメルはより主観的であり、開発チームの選択に依存します。たとえば、20行を超えるメソッドを複雑と見なすチームもあれば、上限を30行に設定するチームもあります。ツールがコードスメルを検出する場合、チームが関連ルールやしきい値をカスタマイズできるようにもする必要があります。

コードスメルを検出する最良の方法は、コードをデータとして扱うこと

静的解析とは、ソースコードのさまざまな特性を解析し、それらの特性について報告することです。しかし、哲学的には、コードをデータとして扱うことでもあります。これはアプリケーション開発者にとって珍しく感じられるかもしれません。私たちは通常、ソースコードを命令、手続き、アルゴリズムとして考えることに慣れているからです。しかし、コードをデータとして扱うことは非常に強力でもあります。

ソースファイルを解析した後、そのASTを抽出し、コードに関する豊富な有用情報を含むモデルを生成できます。そして、このモデルに対して、SQLに似たコードクエリ言語を使ってクエリを実行できます。

CppDepend は、 CQLinq というコードクエリ言語を提供し、コードベースをデータベースのようにクエリできます。開発者、デザイナー、アーキテクトは独自のクエリを定義して、コードスメルを簡単に見つけられます。

CQLinqでは、コードメトリクス、依存関係、APIの使用状況、その他のモデル情報のデータを組み合わせて、特定のコードスメルを特定する高度なクエリを定義できます。

以下は、最も複雑なメソッドに一致するCQLinqクエリの例です:

bugs

概要

コードベースの問題を検出するには、複数のC++ツールを組み合わせる方がよい場合がよくあります。バグに焦点を当てるツールもあれば、コードスメルも検出できるツールもあります。CppDependは、カスタムクエリを簡単に定義できる方法を提供し、他の静的解析ツールの結果をインポートしてCQLinqでクエリできるようにすることで、これらのアプローチを統合します。

Share this article