• Imagix 4D ユーザガイド
  • 目次

データフロー解析 - 使用方法と制約

データ型の処理

C / C++ の構造体と共用体は、C++ のクラスとともに、集約変数というシンボル型を構成します。一部の [タスクフローチェック] レポートには、これらの集約変数をレポートする方法を調整するためのオプションが用意されています。レポートオプションで Container Summary を選択すると、集約変数の任意のメンバがコンテナ変数の要約で使用されます。例えば、ある構造体のメンバが1つのタスクにセットされ、同じ構造体の別のメンバが別のタスクに設定された場合、[複数のタスクでセットされる変数] レポートにはメンバが表示されませんが、構造体変数は表示されるのです。

これに対して配列は、レポート内で単一の変数として処理されます。この動作は、配列指標が動的な式となる場合があることに起因します。したがって通常は、割り当てられている配列コンポーネントを識別することは不可能です。

"[共用体/ビットフィールドのメンバを別に解析]" オプションを使用して、解析時における共用体もしくはビットフィールドの一部であるメンバの処理方法を制御します。このオプションを有効にすると、構造体の場合と同じように、共用体メンバは別々の独立した変数として追跡されます。逆に無効とする際には、配列の場合と同じように、メンバは同じ変数であるとみなされるのです。後者のケースにおいて共用体メンバ un.member1 への代入は、un.member2 などの共用体メンバすべてへの代入として解釈されます。また、このオプションはビットフィールドにも適用されます。典型的なコンピュータ・アーキテクチャでは、ビットフィールドを割り当てると、メモリ内の単語あるいはバイト全体を更新する必要が生じます。このため、別のタスクから別のビットフィールドへの割り当てが同時に発生すると、この割り当てによって隣接する他のビットフィールドに影響を及ぼす可能性があるのです。

ポインタ式の解析

静的な解析が可能な範囲で、これらのレポートは、ポインタに参照されるオブジェクトを追跡します。ポインタもしくは参照パラメータは、実際のパラメータ変数を追跡し、潜在的な変更を特定するのです。配列に設定されたり、配列のインデックスに使用されたりするポインタによって、配列が変更されます。これらのレポートでは、ポインタを「クリーン」に使用することが想定されています。この場合、ポインタは特定の変数に設定され、その変数でのみ機能し、隣接するメモリ領域に割り当てられている個々の変数に副次的にアクセスすることはありません。

ポインタ式の静的解析は、時間とリソースを多く消費する可能性があります。そこで、ユーザ設定により、4つの解析レベルのうちどれを適用するかを制御します:

**基本のポインタ式** -- 基本モードでは、変数に設定された単一ポインタを追跡します。これにはポインタ型のパラメータが含まれます。ポインタの単一デリファレンス(*ptr)は評価されますが、複数のデリファレンス(**ptrや*(ptr1->ptr2))は評価されません。他のポインタに渡されるポインタは1ステップのみ追跡されます(ptr1 = &var; ptr2 = ptr1; *ptr2)。

**標準のポインタ式** -- 標準モードでは、変数に設定された単一または二重ポインタを追跡します。これにはポインタ型のパラメータが含まれます。ポインタの単一または二重デリファレンス(*ptr、**ptr)は評価されますが、2回以上のデリファレンス(***ptrや*(ptr1->ptr2->ptr3))は評価されません。他のポインタに渡されるポインタは追跡されます(ptr1 = &var; ptr2 = ptr1; *ptr2)。

**複雑なポインタ式** -- 複雑モードでは、最大5レベルのポインタおよびデリファレンスを追跡します。他のポインタに渡されるポインタはこれらのレベルで追跡されます(ptr1 = &var; ptr2 = &ptr1; ptr3 = ptr2; ptr4 = &ptr3; ***ptr4)。

**複雑かつ非表示のポインタ式** -- このモードは複雑モードと同じですが、ポインタ長の整数変数もポインタとして扱います。このモードは、unionやcastを使用して整数変数にポインタを格納するアプリケーション向けです。隠れたポインタは非常に珍しいです。このモードは、追跡する変数の数が劇的に増加するため、計算コストが非常に高くなります。

関数ポインタの処理

呼び出しに関数ポインタを使用するソースコードを解析する場合、これらのレポートはプログラム全体にわたり、そのポインタに対して実行される可能性のある代入をすべて追跡します。その結果、関数ポインタを使用するあらゆる呼び出しについては、グローバル解析で特定された関数のいずれかが呼び出されるものと見なします。これによって大半のケースにおいて、実際の処理内容より、レポートの対象範囲が拡張されるのです。例えば関数ポインタ変数 fp が、あるタスクで func1 へ設定された後に呼び出され、次に別のタスクで func2 へ設定された後に呼び出された場合、これらのレポートでは、func1 と func2 の両関数が、双方のタスクに呼び出されたものと見なします。したがって、func1 あるいは func2 のいずれかで設定されたグローバル変数は、両方のタスクで表示されるのです。関数ポインタを使用する、このような呼び出しの概念は、関数ポインタが関わるレポートすべてに適用されます。

未使用変数制約がありません。
未初期化読み取り変数変数の読み込みが誇張される場合があります。
無用の代入無用な代入が一部、認識されない場合があります。
変数の依存関係無関係の計算処理がリストアップされる場合があります。

タスク間の変数フロー特定のタスクにおける変数の使用が誇張される場合があります。
複数のタスクでセットされる変数無関係の変数または無関係の場所がレポートされる場合があります。
Out of Step(Z)変数無関係の周期遅れ変数がレポートされる場合があります。
リエントラント関数無関係の関数が再入関数として記録される場合があります。
タスクで使用されていない関数未使用の関数がレポートされる場合があります。
クリティカルセクションの不一致無関係の不一致がレポートされる場合があります。
クリティカルセクションでの呼出し無関係の呼び出された関数がレポートされる場合があります。
タスク間のイベントの遷移無関係の待機、通知、クリアがレポートされる場合があります。
タスク内のイベント呼出し無関係の待機、通知、クリアがレポートされる場合があります。

[無用の代入] レポートを除き、レポートされる無関係のインスタンスは偽の正数ですが、レポートでは真の負数が除外されないことに注意してください。

関数ポインタからの呼び出しを追跡する際の、ソースコード・アナライザのデフォルトの動作では、関数ポインタ型を持つポインタへの代入のみを記録します。場合により、アプリケーションは関数ポインタを格納するために "void *" ポインタを使用します。このような場合には、 ソースアナライザのオプション -voidfptr を追加することで、それらの代入が記録され、これによりデータフロー解析で認識されます。

解析メッセージ

一部の [フローチェック] レポートには、次のような警告が記述されることがあります。

Statement or partial statement in file.x line xx not reachable and eliminated from analysis
これらの警告はデータフロー解析に問題があることを示しているわけではありません。単に、意図しない状況で到達不可能なコード行がある場合にフラグを立てるものです。到達不可能な行は、[到達不能な文] レポートの対象でもあり、次のような場合に発生します。
  • 静的に真または偽に評価される条件で、もう一方の分岐にコードがある場合
  • goto、break、continue などの、制御の移行の後に現れるコード

警告メッセージは、以下の例の注記のある行に対して生成されます。

#define TRUE 1
#define TEST TRUE
void funcA () {
    int condition1, condition2;
    if (TEST) {
        funcB();
    } else {
        not_reached_due_to_condition();  /* 到達不可能として指摘 */
    }
    while (condition1) {
        if (condition2)
            return;
        else continue;
        occurs_after_control_transfer();  /* 到達不可能として指摘 */
    }
    return;
}

メモリ要件

関数制御ロジック内および関数の境界を越えるデータフロー解析では、[フローチェック] レポートによるきわめて集中的な計算が行われます。中規模のプログラムでさえ、処理時間とメモリ双方の消費量が多くなることがあるのです。

32 bit 版のオペレーティング・システムの場合、2 GB または 4 GB の制限を超える可能性があります。大規模なプロジェクトに対応するためには、64 bit 版のオペレーティング・システムで、Imagix 4D の 64 bit 版を使用し、仮想メモリに 16 GB、物理メモリには最低 8 GB、もしくは可能であれば 16 GB を割り当てることが推奨されます。さらに、Imagix 4D データフロー・エンジンには、専用の仮想メモリシステムが搭載されており、データフロー解析に使用されるメモリは、ハード・ドライブにページングされます。この件に関する詳細な説明は、プロジェクト・リソースのページに記載されています。