PVS-Studio の独立したレビュー (Linux、C++)

PVS が Linux での分析方法を学習したという出版物を見て、自分のプロジェクトでそれを試してみることにしました。 そして、そこから出てきたのがこれです。


ページ内容

  1. プロたち
  2. コンズ
  3. 結果
  4. 後書き

プロたち

レスポンシブサポート

試用版キーをリクエストしたところ、同じ日に送ってくれました。

かなり明確なドキュメント

問題なくアナライザーを起動することができました。 コンソール コマンドのヘルプも利用できます (ただし、ここにはいくつかの不満があります。セクションを参照してください) コンズ).

マルチスレッド解析の可能性

アナライザーには「標準」オプションがあります -jを使用すると、複数のタスクで分析を並行して実行できます。 これにより時間を大幅に節約できます。

優れた視覚化

テキストから小さなウェブ銃口まで、さまざまな出力形式。 Web インターフェイスは便利で簡潔で、コード内の行の横にヒントと診断の説明へのリンクがあります。.

アセンブリへの簡単な組み込み

すべてのドキュメントは Web サイトにあります。プロジェクトが CMake を使用してビルドされている場合は、すべてが非常に簡単であるとしか言えません。

適切な診断説明

モードで出力を生成する場合 fullhtml、各メッセージには、説明、コード例、追加リンクを含む診断の説明へのリンクが含まれています。

コンズ

アナライザーによる C++ 言語の無知

残念ながら、コードが完全に正しい場合でも、PVS は構文エラーを起こしたり、誤検知メッセージを生成したりすることがあります。

たとえば、以下を返す関数があります。 void:

template <typename T>
auto copy (const void * source, void * destination)
    ->
        std::enable_if_t
        <
            std::is_copy_constructible<T>::value
        >
{
    new (destination) T(*static_cast<const T *>(source));
}

はい、キーワード auto 意味することができます void、それが目的です オート。 しかし、PVS は次のメッセージを生成しました。

dynamic_tuple_management.hpp:29:1: error: V591 Non-void function should return a value.
dynamic_tuple_management.hpp:29:1: error: V2542 Function with a non-void return type should return a value from all exit paths.

非常に遅いサイト

はい、Web インターフェイスの各メッセージの横に、対応する診断の説明と例へのリンクがあります。 ただし、リンクをクリックすると、かなり長い時間待つ必要があり、場合によってはそれが発生します 504ゲートウェイのタイムアウト.

言語

すべての説明はロシア語であり、素晴らしいです。 ただし、レポートからのリンクは常に英語版につながります。 言語を切り替えて、ロシア語で診断をすぐに表示できるようにすると便利です。 インターフェースにはそのようなオプションが見つかりませんでした。

コンソール経由で診断レベルを操作するのは不便です

XNUMX つのコマンドが使用されたという事実から始めましょう (これは pvs-studio-analyzer и plog-converter) 診断を指定するためのさまざまな形式。

ヘルプ pvs-studio-analyzer 読み取り:

-a [MODE], --analysis-mode [MODE]
    MODE defines the type of warnings:
    1 - 64-bit errors;
    2 - reserved;
    4 - General Analysis;
    8 - Micro-optimizations;
    16 - Customers Specific Requests;
    32 - MISRA.
    Modes can be combined by adding the values
    Default: 4

どこに行こうか探すのに長い時間を費やした 追加する (「値の追加」) キー。 それらをカンマで区切ってリストしてみました。

pvs-studio-analyzer analyze ... -a 1,4,16

キーを数回登録しようとしました:

pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16

そしてそのとき初めて、これがビットマスクだと気づきました。 そして、あなたが必要とするのは まとめるとしない 追加する 意味。 たとえば、一般的な診断、マイクロ最適化および MISRA の診断を取得するには、それらを合計する必要があります (4 + 8 + 32 = 44)。

pvs-studio-analyzer analyze ... -a 44

ユーザー インターフェイスでビットマスクを使用することは、一般的に悪い方法です。 これらすべてを内部で要約し、一連のフラグをユーザーに対して設定できます。

さらに、ユーティリティもあります plog-converter、人間が判読できる静的解析情報を生成します。 彼女には他にも問題がある。

プログラムのヘルプ plog-converter レポート:

-a, --analyzer            Specifies analyzer(s) and level(s) to be
                          used for filtering, i.e.
                          'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
                          Default: GA:1,2

以前は存在しなかったいくつかの「レベル」がここに表示されましたが、ドキュメントにもそれらについて何も見つかりませんでした。

一般に、それは明らかではありません。 だからこそ、すべてを最大限に設定しました。

Catch に関する愚かな悪口の集まり

私が分析した XNUMX つのプロジェクトのうち XNUMX つは単体テスト ライブラリを使用しています Catch2。 そして、メッセージの大部分 (!!! 90 つは 138 件中 297 件、もう 344 つは XNUMX 件中 XNUMX 件!!!) は次の形式です。

PVS-Studio の独立したレビュー (Linux、C++)

マルチスレッドを考慮していません

変化しないと思われる変数や無限ループに関する誤検知が多数ありますが、これらの変数の処理は別のスレッドから行われます。そうでない場合、単体テストは機能しません。

PVS-Studio の独立したレビュー (Linux、C++)

しかし、静的アナライザーはこれを考慮することさえできるのでしょうか? わかりません。

結果

PVS は私のオープンソース プロジェクトに本当のバグを見つけられませんでした バースト и プロキシマ、そして作業草案にも記載されていますが、明らかな理由により、これを提示することはできません。 確かに、いくつかの欠点はすでに発見され、以前に修正されていることに留意する価値があります。 Cppチェック и scan-build.

一般に、これらすべてのアナライザーからの印象はほぼ同じです。はい、何かをキャッチし、時には重要なものさえもキャッチしますが、全体的にはコンパイラーで十分です。

私たちのチームが最小限のクソコードの生成を可能にするソフトウェア開発手法を使用している可能性があります (そして私は個人的にそう思いたい)。 問題を勇敢に克服するよりも、問題を生み出さない方が良いのです。

したがって、私は、誰かの足を撃ち落としたり、熊手で額を殴ったりしないように C++ で記述する方法についてアドバイスをさせていただきます。

コンパイラ診断を最大限に活用する

私たちのチームは次のコンパイル オプションを使用します (また、そうするようアドバイスします)。

-Werror

-Wall
-Wextra
-Wpedantic

-Wcast-align
-Wcast-qual
-Wconversion
-Wctor-dtor-privacy
-Wenum-compare
-Wfloat-equal
-Wnon-virtual-dtor
-Wold-style-cast
-Woverloaded-virtual
-Wredundant-decls
-Wsign-conversion
-Wsign-promo

プロジェクトでこれらを有効にして、コードについて多くのことを学びましょう。

基準に固執する

標準的な類似物がある場合はプラットフォームに依存するものを使用しないようにしてください。また、それなしでは絶対にできない場合は、それらをマクロ (またはその他のもの) 用の特別なブロックでラップし、サポートされていない条件でコードをコンパイルしないようにしてください。

標準の操作セマンティクスに固執する

加算は加算である必要があり、乗算は乗算である必要があり、関数呼び出しは関数呼び出しである必要があり、コピーはコピーである必要があり、キャリーはキャリーである必要があり、コンテナーは反復可能である必要があり、イテレーターはプロモーションを持っている必要があります ++ そして逆参照 *。 などなど。

考え方は明確だと思います。 法的拘束力はありませんが、コードのすべてのユーザーと読者が期待する確立された規則があります。 他人を出し抜こうとしないでください。そうしないと、自分自身が出し抜かれてしまいます。

互換性のあるコードを書く

まず第一に、私は標準ライブラリを意味します。 クラスと関数のインターフェイスが標準ライブラリや他のライブラリ (Boost など) で使用できることが非常に望ましいです。

STL インターフェイスと Boost インターフェイスをぜひご覧ください。 まれな例外を除いて、そこには価値のあるロールモデルがいます。

オープンソースツールを最大限に活用する

同じ静的解析を行うために、CMake ビルド システムを使用して任意のプロジェクトに XNUMX 回だけ接続できるオープンな無料ツールが少なくとも XNUMX つあります。

これについては、私の最近の出版物で詳しく読むことができます.

後書き

最後に、私は PVS やその他の静的アナライザーを使用しないことを推奨しているわけではないことを強調したいと思います。 ただし、静的アナライザーがコード内の重大なエラーを常に検出することがどのようにして起こったのかを考えてみることをお勧めします。

これは単なる結果です。 原因を探って取り除く必要があります。

出所: habr.com

コメントを追加します