[変数の依存関係] レポート
グローバル変数、静的変数、およびローカル変数の場合、変数の依存関係は変数の値に影響する計算を示します。 これは、データフローの変数テーブル表示に表示される情報と同じですが、レポートはプロジェクト内のすべての変数にまたがっています。 次の例を考えてみましょう。
int gv = 1, gv2;
int *pgv = &gv2;
int func1 (int p1, int *p2) {
p1++;
gv2 = *p2;
if (p1)
*p2 = 5;
else
*p2 = p1 + *p2;
int z = p1 + *p2;
pgv = &gv;
return z + gv;
}
void func2() {
int x = 1, y = 2;
if (gv) gv = 2;
int ret = func1 (x, &y);
int t = gv2;
*pgv = 5;
if (gv)
int d = x + y;
gv++;
y = x + gv;
gv = ret + x;
}
|
レポート設定では、変数の値に寄与する上流(ファンイン)割り当て、または変数への割り当ての影響を受ける下流(ファンアウト)ステートメントのいずれかを調べることを選択します。 どちらを選択するかは、何を達成しようとしているかによって異なります。
Contributing Statementsモード | プログラム内の変数の値の読み取りを調べている場合、この値がどのようにより早く他の値から計算されるかを知りたいことがよくあります。 これは通常、コードを理解またはデバッグするために使用されます。 |
Impacted Statementsモード | 特定の場所の変数への割り当てが変更された場合にどうなるかを知りたい場合は、通常、どのステートメントが影響を受ける可能性があるかを知ります。 これは通常、what-if分析または変更分析に使用されます。 |
選択した内容は、レポートのヘッダファイルに示されます。:
変数の依存関係
設定:
グローバル変数: 表示
静的変数: 表示
ローカル変数: 表示
投稿文の表示(ファンイン): 表示
影響を受けるステートメントを表示(ファンアウト): 省略
変数 ファイル
使用カテゴリ
機能を含む
使用法
Contributing Statements
|
レポートには、各変数の結果がリストされます。 各変数固有セクションには、その変数に直接関連する割り当てとステートメントが表示されます。 貢献ステートメントを表示するように構成されたレポート(ファンイン)で、上記のサンプルコードのグローバル変数gvに対応するセクションは次のとおりです。
gv calls.cpp (1)
Assignments through Reference
func2 calls.cpp
23 *pgv = 5;
Contributing Statements
file level calls.cpp
2 int *pgv = &gv2;
func1 calls.cpp
13 pgv = &gv;
Direct Assignments
file level calls.cpp
1 int gv = 1, gv2;
func2 calls.cpp
20 if (gv) gv = 2;
26 gv++;
Contributing Statements
file level calls.cpp
1 int gv = 1, gv2;
func2 calls.cpp
20 if (gv) gv = 2;
23 *pgv = 5;
28 gv = ret + x;
Contributing Statements
func2 calls.cpp
19 int x = 1, y = 2;
21 int ret = func1 (x, &y);
Return Value
func1 calls.cpp
15 return z + gv;
Contributing Statements
file level calls.cpp
1 int gv = 1, gv2;
func2 calls.cpp
20 if (gv) gv = 2;
Used in Condition
func2 calls.cpp
20 if (gv) gv = 2;
Contributing Statements
file level calls.cpp
1 int gv = 1, gv2;
24 if (gv)
Contributing Statements
file level calls.cpp
1 int gv = 1, gv2;
func2 calls.cpp
20 if (gv) gv = 2;
23 *pgv = 5;
Used in Expression
func2 calls.cpp
27 y = x + gv;
Contributing Statements
file level calls.cpp
1 int gv = 1, gv2;
func2 calls.cpp
20 if (gv) gv = 2;
23 *pgv = 5;
26 gv++;
|
変数のセクションでは、変数に関係するステートメントは、最初に使用カテゴリ、次に包含関数、次に使用法ごとに整理され、実際のステートメントが発生する行番号とソースコードスニペットとして表示されます。
gvのこのセクションの[直接割り当て]カテゴリには、gvの値が直接設定されているすべてのステートメントのリストがあります。包含関数/ロケーションレベルで、gvがファイルレベルで初期化され、またfunc2で直接設定されていることがわかります。また、使用ステートメントレベルでは、func2内で、gvは3行(20、26、および28)に設定されます。
報告されているこれらの使用状況ステートメントごとに、データフロー内の直接関連するステートメントが表示されます。
「gv = ret + x;」の行28でのgvの直接割り当てを検討します。このレポートはファンインを表示するように設定されているため、28行目のサブセクションにはContributing Statementsという名前が付けられ、アップストリームの依存関係が表示されます。この行でgvに割り当てられた値に寄与する2つの変数retとxがあり、Contributing Statementsサブセクションには、これらの各変数の値が設定されるステートメントがリストされています。
以下は、影響を受けるステートメントを表示するようにレポートが構成されている場合の同じ変数のセクションです(ファンアウト)。
gv calls.cpp (1)
Assignments through Reference
func2 calls.cpp
23 *pgv = 5;
Impacted Statements
func2 calls.cpp
24 if (gv)
26 gv++;
27 y = x + gv;
Direct Assignments
file level calls.cpp
1 int gv = 1, gv2;
Impacted Statements
func1 calls.cpp
15 return z + gv;
func2 calls.cpp
20 if (gv) gv = 2;
24 if (gv)
26 gv++;
27 y = x + gv;
func2 calls.cpp
20 if (gv) gv = 2;
Impacted Statements
func1 calls.cpp
15 return z + gv;
func2 calls.cpp
24 if (gv)
26 gv++;
27 y = x + gv;
26 gv++;
Impacted Statements
func2 calls.cpp
26 gv++;
27 y = x + gv;
28 gv = ret + x;
Reference Taken
func1 calls.cpp
13 pgv = &gv;
Impacted Statements
func1 calls.cpp
13 pgv = &gv;
15 return z + gv;
func2 calls.cpp
24 if (gv)
26 gv++;
27 y = x + gv;
|
gvのセクションは同じ構成(使用カテゴリ > 使用場所 > 使用ステートメント)ですが、異なるステートメント(および対応する異なる使用カテゴリ)が報告されます。Contributing Statementsモードでは、変数のすべての使用方法がリストされます(割り当て、パラメーターの受け渡し、または条件の右側)。使用法ごとに、以下の「Contributing Statements」サブセクションに、割り当てまたはパラメータの受け渡しの値がどこから来るかが示されています。
Impacted Statementsモードの場合は、逆が表示されます。レポートには、割り当てとパラメータの受け渡しがリストされます。報告された使用法ごとに、Impacted Statementsサブセクションが続き、変数の使用方法がすべてリストされます。
カテゴリは完全に異なるわけではなく、2つのモード間で一部重複していますが、フローの方向のために、特定のタイプは意味がありません。
1行目のgvのファイルレベルの直接割り当ては、選択されているモードに応じてサブセクションがどのように変化するかの例を示しています。 [Impacted Statementsを表示]が選択されている場合、この割り当てにはサブセクションが関連付けられています。 1行目のgvの使用法は単純な初期化であるため、Contributing Statementsはありません。ただし、コードでgvが使用されているため、レポートにはgvが直接使用される各ダウンストリームステートメントがリストされます。これらのステートメントは初期化によって影響を受けるためです。
使用カテゴリ
直接割り当て | これらは、割り当てステートメントの左側に明示的に変数名を持つ変数への割り当てです。 |
参照による割り当て | これらは、変数への参照になりうるポインタを介した変数への割り当てです。 |
参照の取得 | これらは、割り当ての右側にある変数の参照を使用したポインタ変数への割り当てです。そのポインタは、後でその変数の読み取りまたは設定に使用できることが期待されています。 |
式で使用 | これらは、他の変数への割り当ての式で、変数の使用、または間接参照される変数へのポインタの使用です。配列のインデックス式にも使用できます。 |
条件で使用 | これらは、if、while、do、またはswitchステートメントの条件で、変数の使用、または間接参照される変数へのポインタの使用です。
|
実際のパラメータとして使用 | これらは、関数に渡される式での変数の使用、または間接参照される変数へのポインタの使用です。
|
ルート関数パラメータ | これらは、呼び出し元を持たないルート関数の仮パラメータ用です。変数に値があることを示すプレースホルダーですが、その値については何もわかっていません。 |
パラメータの割り当て | これらは、呼び出しの場所にある非ルート関数の仮パラメータ用です。これらは、実際のパラメータの仮パラメータへの割り当てを示します。 |
参照パラメータによる割り当て | これらは、変数への参照になり得るポインタを介した変数への割り当てです。ポインタは関数のパラメータであり、変数への参照は呼び出しで設定されます。
|
戻り値 | これらは、returnステートメントでの変数の使用、または逆参照される変数へのポインタの使用です。
|
データフローとの比較
変数の依存関係レポートとデータフローツールは密接に関連しています。どちらも、変数の値に影響する計算を決定して表示します。どちらも、アップストリームデータフローを解析する(Contributing Statementsを表示する)か、ダウンストリームフローを追跡する(Impacted Statementsを表示する)かを選択できます。特に、データフローの変数テーブル表示は、変数依存関係レポートに似ています。
データフローはソフトウェアの特定の変数(通常はソースコードの特定の行)に焦点を合わせるため、レポートとツールが異なる重要な方法がいくつかあります。
ファイルエディタの右クリックメニューを使用してソースコードの特定の行からデータフローを呼び出すと、その特定のステートメントに関してすべてのデータフロー依存関係解析が行われます。対照的に、特定の変数について、変数の依存関係はすべての可能な開始点を解析します。使用法の下にリストされているのはこれらの開始点であり、カテゴリおよび機能の場所ごとに整理されています。使用法エントリの完全なリスト自体は、変数の研究に役立つ場合があります。レポートを使用して特定の使用法を調べるには、関心のあるステートメントを見つけ、それに続く「Contributing Statements」または「Impacted Statements」サブセクションを調べます。
データフローフォーカスの限定された範囲により、ターゲットステートメントまたは変数のデータフローの完全な階層を表示でき、ターゲットに出入りする変数のチェーン全体にわたって割り当てを推移的に追跡できます。すべての変数のすべての使用状況ステートメントが報告される変数依存関係レポートでは、各使用状況ステートメントの寄与ステートメントまたは影響を受けるステートメントサブセクションは、直接影響を受けるステートメントに限定されます。
その結果、変数間でデータフローを推移的に追跡するには、関連する変数の変数依存関係のセクションを調べる必要があります。特定の関連変数は、Contributing StatementsまたはImpacted Statementsサブセクションに表示されるソースコードスニペットを通じて識別できます。その関連変数のセクションに移動するには、レポートウィンドウのシンボルベースおよび文字列ベースの検索機能が役立ちます。
これらの支援があっても、解析を変数依存関係レポートのみの使用に限定する場合、このプロセスは面倒な場合があります。最初に変数依存性レポートを使用して目的の割り当てを特定し、次にデータフローを起動してそのような割り当てを詳細に調べることが、ソフトウェアの完全な推移的データフローを調べるための最も迅速かつ簡単なアプローチです。
|