リンカーとライブラリ

ウィークシンボル

生成中の出力ファイルタイプがどのようなタイプであっても、未解決のウィークシンボル参照によって重大なエラー状態は発生しません。

静的実行可能プログラムを生成中の場合は、シンボルは絶対シンボルに変換され、ゼロの値が割り当てられます。

動的実行可能ファイルまたは共有オブジェクトの作成中の場合は、シンボルは定義されていないウィーク参照として残され、値には 0 が割り当てられます。プロセスの実行中に、実行時リンカーがこのシンボルを検索します。一致が検出されない場合、実行時リンカーは重大な実行時再配置エラーを生成する代わりに、その参照がゼロのアドレスに結合されます。

従来は、これらの定義されていないウィーク参照シンボルは、機能の存在をテストするためのメカニズムとして使用されていました。たとえば、次の C コードフラグは、共有オブジェクト libfoo.so.1 内で次のように使用されていました。


#pragma weak    foo

extern  void    foo(char *);

void bar(char * path)
{
        void (* fptr)(char *);

        if ((fptr = foo) != 0)
                (* fptr)(path);
}

libfoo.so.1 を参照するアプリケーションを構築すると、シンボル foo の定義が検出されたかどうかに関係なく、リンク編集は、正常に完了します。アプリケーションの実行中に、機能アドレスがゼロ以外をテストすると、その機能が呼び出されます。ただし、シンボル定義が検出されない場合には、機能アドレスはゼロをテストするため、その機能は呼び出されません。

コンパイルシステムは、定義されないセマンティクスを保持しながら、このアドレスの比較テクニックを参照します。その結果、テストステートメントは最適化処理によって削除されます。また、実行時シンボル結合メカニズムは、このテクニックの使用にほかの制限を課します。これらの制限によって、すべての動的オブジェクトでは一致モデルを利用できなくなります。


注 –

このような未定義ウィーク参照は推奨されていません。代わりに dlsym(3C)RTLD_DEFAULT と使用するか、または RTLD_PROBE ハンドルを使用して、シンボルの有無をテストします。「機能のテスト」を参照してください。