メインコンテンツ

未初期化ローカル変数チェックのレビューと修正

このトピックでは、Polyspace® Code Prover™[未初期化ローカル変数] チェックの結果を体系的にレビューする方法を説明します。

[未初期化ローカル変数] チェックの修正を判断するまでこれらの手順の 1 つ以上に従います。このチェックを修正する方法は複数あります。チェックおよびコードの例については、未初期化ローカル変数を参照してください。

特にオレンジ チェックに対して、チェックが実際のエラーを表すのではなく、コードに該当しない Polyspace 前提条件を表していると判定できます。前提条件を緩和するのに解析オプションを使用できる場合、そのオプションを使用して検証を再実行します。それ以外の場合は、結果またはコードにコメントおよび正当化情報を追加できます。

すべてのチェックに適用される一般的なワークフローについては、Polyspace デスクトップ ユーザー インターフェイスでの Code Prover の結果の解釈またはPolyspace Access Web インターフェイスでの Code Prover の結果の解釈 (Polyspace Access)を参照してください。

手順 1: チェック情報の解釈

[未初期化ローカル変数] エラーが表示される変数の上にカーソルを置きます。

ツールヒントに示されている場合、未初期化である変数について考えられる根本原因を取得します。

前述の例では、スタブ関数 initialize が考えられる原因として識別されています。

考えられる解決方法: チェックを回避するために、initialize がその引数に書き込むように指定できます。詳細については、スタブ関数に関する Code Prover の仮定を参照してください。

手順 2: チェックの根本原因の判定

以下の手順は、Polyspace ユーザー インターフェイスでのみ実行できます。

  1. 変数定義を検索します。変数を定義する際に変数を初期化するかどうかを確認します。

    オプションが存在する場合、変数を右クリックし、[定義に移動] を選択します。

  2. 定義時に変数を初期化しない場合、変数のすべてのインスタンスを参照します。インスタンスの任意の変数を初期化するかどうかを決定します。

    次のいずれかを行います。

    • [ソース] ペインで変数をダブルクリックします。

      変数の前のインスタンスは強調表示されます。上にスクロールし、インスタンスを検索します。

    • [ソース] ペインで変数を右クリックします。[すべての参照を検索] を選択します。

      [検索] ペインで前のインスタンスを選択します。

    考えられる解決方法: 変数を初期化しない場合、初期化できるインスタンスを特定します。

  3. 変数を初期化するインスタンスを見つけた場合、[未初期化ローカル変数] エラーが表示されるスコープで初期化を実行できるかどうかを特定します。

    たとえば、if ... elseif ... else ステートメントの一部の分岐でのみ変数を初期化するとします。ステートメント外部で変数を使用する場合、変数が未初期化の場合があります。

    考えられる解決方法:

    • 変数を使用するのと同じスコープで初期化を実行します。

      前述の例では、if ... elseif ... else ステートメントの外部で初期化を実行します。

    • より小さいスコープのブロック内で初期化を実行しますが、ブロックが常に実行されることを確認します。

      前述の例では、if ... elseif ... else ステートメントのすべての分岐で初期化を実行します。ステートメントの 1 つの分岐が常に実行されることを確認します。

手順 3: チェックの一般的な原因の検索

[未初期化ローカル変数] チェックの一般的な原因を確認します。

  • 変数を使用する前に参照またはポインターによって変数を別の関数に渡すかどうか確認します。関数本体で変数を初期化するかどうかを判定します。

    関数本体に移動するには、オプションが存在する場合は、関数を右クリックし、[定義に移動] を選択します。

  • 到達不能なコードで変数を初期化するかどうかを判定します。

    たとえば、 break または return ステートメントの後のコードで変数を初期化するとします。

    考えられる解決方法: 到達不能コードを調べます。詳細については、到達不能コード チェックのレビューと修正を参照してください。

  • 実行時に回避される可能性のあるコードで変数を初期化するかどうかを判定します。

    たとえば、関数内部のループで変数を初期化します。ただし、特定の関数の引数に対してループは実行されません。

    考えられる解決方法:

    • 宣言時に変数を初期化します。

    • コードが回避される可能性があるときは調べます。コードが回避できるかどうかを判定します。

  • 変数が配列である場合、配列のすべての要素を初期化するかどうかを判定します。

  • 変数が構造化された変数である場合、構造体のすべてのフィールドを初期化するかどうかを判定します。

    構造体の特定のフィールドを初期化しない場合、フィールドが未使用であるかどうかを確認します。

    考えられる解決方法: コードでフィールドを使用する場合、構造体のフィールドを初期化します。

手順 4: Polyspace の前提条件へのチェックをトレース

コードの前方で発生する Polyspace 前提条件にオレンジ チェックをトレースできるかどうかを確認します。前提条件があてはまらない場合、結果またはコードにコメントまたは正当化情報を追加します。Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処またはPolyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access)を参照してください。

たとえば、参照またはポインターによって変数を別の関数に渡すとします。関数本体内で変数を初期化することを意図しますが、検証時に関数本体を提供しません。ここで、次のようにします。

  • Polyspace は、関数が変数を初期化しない可能性があると仮定します。

  • 関数呼び出しの後に変数を使用しない場合、Polyspace は変数が初期化されてない可能性があると見なします。変数に [未初期化ローカル変数] オレンジ チェックが生成されます。

詳細については、Code Prover 解析の前提条件を参照してください。

メモ

オレンジ チェックを正当化する前に、コード設計を改善できるかどうかを十分に検討してください。

このチェックを無効にする

このチェックは無効にできます。このチェックを無効にすると、Polyspace は宣言で、変数はその型で許容される全範囲の値を取ると仮定します。詳細については、未初期化のチェックを無効にする (-disable-initialization-checks)を参照してください。