メインコンテンツ

extern "C" ブロックに関連する Polyspace リンク作成エラーの修正

extern C 関数

一部の関数はあるファイルの extern "C" { } ブロック内では宣言されますが、別のファイル内では宣言されないことがあります。この場合は、リンクが異なるためにリンク エラーが発生します。これは、ANSI® 規格で禁止されているためです。

元のコード:

extern "C" {
    void* memcpy(void*, void*, int);
}
class Copy
{
public:
    Copy() {};
    static void* make(char*, char*, int);
};
void* Copy::make(char* dest, char* src, int size)
{
    return memcpy(dest, src, size);
}

エラー メッセージ:

Pre-linking C++ sources ... 

<results_dir>/test.cpp, line 2: error: declaration of function "memcpy" 
is incompatible with a declaration in another translation unit 
(parameters do not match) 
|            the other declaration is at line 4096 of "__polyspace__stdstubs.c" 
|    void* memcpy(void*, void*, int); 
|          ^ 
|          detected during compilation of secondary translation unit "test.cpp" 

関数 memcpy は、外部 "C" 関数および C++ 関数として宣言されています。これにより、リンクの問題が発生します。実際、関数管理の動作は、C 関数と C++ 関数のどちらに関連しているかによって異なります。

このようなエラーが発生した場合には宣言を統一すると解決します。たとえば、上記の C 関数は extern "C" { } で囲みます。

もう 1 つの解決法は、許容オプション -no-extern-C を使用することです。このオプションは、extern "C" 宣言をすべて削除します。

一部のスタブ化された ANSI 規格関数の機能制限

  • signal.h は機能制限付きでスタブされます。つまり、関数 signal および関数 raise は、関連する機能モデルに従いません。関数 raise が呼び出されても、信号番号に関連付けられている保存された関数ポインターは呼び出されません。

  • 関数 setjmp および関数 longjmp が呼びされても、ジャンプは実行されません。

  • errno.h は部分的にスタブされます。一部の数学関数は errno を設定しません。その代わり、ASRT チェックを使用して値域エラーまたは定義域エラーが発生した場合にはレッド エラーを生成します。

コンパイル オプション POLYSPACE_STRICT_ANSI_STANDARD_STUBS (-D フラグ) を使用することもできます。このオプションは ANSI C 規格 libC の拡張のみを非アクティブにします。これには次の関数が含まれます。bzerobcopybcmpchdirchownclosefchownforkfsyncgetlogingetuidgeteuidgetgidlchownlinkpipereadpreadresolvepathsetuidsetegidseteuidsetgidsleepsyncsymlinkttynameunlinkvforkwritepwriteopencreatsigsetjmp__sigsetjmp および siglongjmpare