メインコンテンツ

未定義の識別子に関する Polyspace コンパイル エラーの修正

問題

Polyspace® の検証がコンパイル段階で失敗し、未定義の識別子に関するメッセージが表示されます。

このメッセージは、Polyspace で変数定義が見つからないことを示しています。したがって、変数タイプが特定できません。

考えられる原因: ファイルが見つからない

対象のソース コードに変数定義が含まれていません。たとえば、Polyspace で見つからないインクルード ファイルで変数が定義されている場合などです。

ソース コードで #include されたインクルード ファイルが Polyspace プロジェクトに追加されていない場合、事前の警告が表示されます。

Warning: could not find include file "my_include.h"

解決法

変数定義がインクルード ファイルにある場合は、そのインクルード ファイルを含むフォルダーを追加します。

  • Polyspace デスクトップ製品のユーザー インターフェイスで、このフォルダーをプロジェクトに追加します。

    詳細については、ユーザー インターフェイスでの Polyspace の実行を参照してください。

  • コマンド ラインで、コマンド polyspace-bug-finder にフラグ -I を使用します。

    詳細は、-I を参照してください。

考えられる原因: 認識されないキーワード

変数ではコンパイラで認識されるキーワードが表現されていますが、ANSI® C 標準の一部ではありません。したがって、Polyspace では認識されません。

たとえば、一部のコンパイラは __SP をスタック ポインターへの参照として解釈します。

解決法

Polyspace で認識されないキーワードを変数が表現している場合は、ソース コードまたは前処理済みのコードに由来するキーワードを置き換えるか削除します。

前処理済みのコードに由来するキーワードを削除するか置き換えると、ソース コードはそのままでコンパイル エラーを回避できます。次のいずれかを行います。

  • 解析オプションを使用して、未知の各キーワードを置き換えるか削除します。コンパイラ固有のキーワードを ANSI C 規格の対応するキーワードに置き換えます。

    解析オプションについての詳細は、[プリプロセッサ定義] (-D) を参照してください。

  • #define 命令を使用して、未知のキーワードを別のヘッダー ファイルで宣言します。そのヘッダー ファイルを、解析オプションを使用して指定します。

    解析オプションについての詳細は、インクルード (-include) を参照してください。ヘッダー ファイルの例は、コンパイル オプションの効率的な収集を参照してください。

考えられる原因: 宣言が #ifdef ステートメントに組み込まれている

変数がプリプロセッサ命令 #ifdef macro_name の分岐で宣言されています。たとえば、変数 max_power の宣言が次のようになっているとします。

#ifdef _WIN32
  #define max_power 31
#endif

コンパイル ツールチェーンでは、マクロ macro_name が暗黙的に定義されていると見なされ、#ifdef の分岐が実行される可能性があります。しかし、Polyspace のコンパイルでは、マクロが定義されていると見なされない場合があります。そのため、#ifdef の分岐が実行されず、変数 max_power が宣言されません。

解決法

コンパイル エラーを回避するには、以下のいずれかを行います。

  • [ターゲットおよびコンパイラ] のオプションを使用して、コンパイラを直接指定します。たとえば、Visual C++® コンパイラをエミュレートするには、[コンパイラ][visual12.0] に設定します。ターゲットおよびコンパイラを参照してください。

  • オプション [プリプロセッサ定義] (-D) を使用してマクロを明示的に定義します。

メモ

ビルド コマンドをトレースして Polyspace を作成した場合は、[ターゲットおよびコンパイラ] のほとんどのオプションが自動的に設定されます。

考えられる原因: プロジェクトがデバッグ ビルド以外から作成されている

これが原因になる可能性があるのは、assert ステートメント (または ASSERTVERIFY など等価の Visual C++ マクロ) に未定義の識別子がある場合だけです。

通常、このエラーには以下のようにして遭遇します。Polyspace プロジェクトがデバッグ モード以外でビルド システムから作成されています。このプロジェクトの解析を実行すると、assert ステートメントに未定義の識別子があるためにコンパイル エラーが発生します。たとえば、識別子 my_identifier#ifndef NDEBUG で次のように定義されているとします。

#ifndef NDEBUG
int my_identifier;
#endif

C 標準では、NDEBUG マクロが定義されている場合、すべての assert ステートメントを無効にしなければなりません。

ほとんどの IDE では、NDEBUG マクロはビルド システムで定義されます。IDE でソース コードをビルドする場合、デバッグ モード以外では前処理で #ifndef NDEBUG ステートメントのコードが削除されます。たとえば、前述の例では、my_identifier が定義されません。my_identifier が assert ステートメントにしかない場合、assert ステートメントは NDEBUG で無効にされるため、いずれも使用されません。未定義の識別子によるコンパイル エラーは発生せず、ビルド システムが正常に実行されます。

Polyspace では、検証を強化するために内部で assert ステートメントが使用されているため、NDEBUG マクロが定義されていても assert ステートメントは無効にされません。

ビルド システムから Polyspace プロジェクトを作成する場合、ビルド システムで NDEBUG マクロが定義されていると、Polyspace プロジェクトに対しても定義されます。Polyspace では、前処理で #ifndef NDEBUG ステートメントのコードは削除されますが、assert ステートメントは無効になりません。コードの assert ステートメントが #ifndef NDEBUG ステートメントのコードに依存していると、コンパイル エラーが発生する可能性があります。

前述の例の場合は、次のようになります。

  • my_identifier の定義が前処理で削除されます。

  • assert ステートメントは無効になりません。識別子 my_identifierassert ステートメントで使用されると、my_identifier が定義されていないためエラーが発生します。

解決法

この問題を回避するには、Polyspace プロジェクトをビルド システムからデバッグ モードで作成します。ビルド システムをデバッグ モードで実行する場合、NDEBUG は定義されません。このビルドから Polyspace プロジェクトを作成すると、Polyspace プロジェクトに対して NDEBUG が定義されません。

プロジェクトの設定に応じて、デバッグ モードでのビルドを有効にするオプションを使用します。たとえば、ビルド システムが gcc ベースの場合は、DEBUG マクロを定義し、NDEBUG の定義を解除できます。

gcc -DDEBUG=1 -UNDEBUG *.c

あるいは、オプション [プリプロセッサ定義] (-D) を使用して前処理済みのコードの assert ステートメントを無効にできます。ただし、Polyspace では assert ステートメントをエミュレートできなくなります。