#pragma weak

説明

#pragma weak ディレクティブを実行すると、シンボルの定義が検出されないときやリンク中にシンボルが複数回定義されていることを検出したときに、リンケージ・エディターがエラー・メッセージを発行するのを阻止します。

構文

構文図を読む構文図をスキップする>>-#--pragma--weak--identifier--+----------------+-------------><
                                '-=--identifier2-'
 

このプラグマは関数とともに使用することを基本条件として設計されていますが、 ほとんどのデータ・オブジェクトに対しても有効に機能します。

このプラグマは初期化されていないグローバル・データや、実行可能ファイルにエクスポートされる共用ライブラリー・データ・オブジェクトと共に使用しないでください。

ダイナミック・リンカーはコマンド行に最初に表示されるオブジェクトに 定義を使用します。 そのため、オブジェクト・ファイルがリンカーに 示される順序は重要です。

プログラム・ソースには、2 つの形式の #pragma weak を 指定できます。

#pragma weak identifier
この形式のプラグマは、identifier を弱いグローバル・シンボル として定義します。identifier への参照は、定義されている場合は identifier 値を使用し、定義されていない場合は、identifier には 0 の値が割り当てられます。

Identifier#pragma weak identifier と同じコンパイル単位に定義されている場合、identifier は弱い定義として扱われます。identifier を使用も宣言もしていないコンパイル単位に #pragma weak が存在する場合、プラグマは受け入れられますが無視されます。

identifier が C++ リンケージを持つ関数を指示するとき は、identifier はその関数の C++ マングル名を使用して 指定しなければなりません。 また、C++ 関数がテンプレート関数の場合は、明示的にテンプレート関数のインスタンスを生成する必要があります。

#pragma weak identifier=identifier2
この形式のプラグマは、identifier を弱いグローバル・シンボル として定義します。identifier を参照するときは、identifier2 の 値を使用します。

identifier2 はメンバー関数にできません。

identifier#pragma weak と同じコンパイル単位で宣言できる場合とできない場合がありますが、このコンパイル単位には定義しないでください。

identifier がこのコンパイル単位で宣言される場合、identifier の宣言は identifier2 の宣言と互換性がなければなりません。 例えば、identifier2 が関数の場合、identifieridentifier2 と同じ戻りの型および引数の型を持っている必要があります。

identifier2#pragma weak と同じコンパイル単位で宣言されていなければなりません。

identifier2 が C++ リンケージを持つ関数を示す場合は、その関数のマングル名を使用して identifieridentifier2 の名前を指定する必要があります。C++ 関数がテンプレート関数の場合は、明示的にテンプレート関数のインスタンスを生成する必要があります。

以下の場合、コンパイラーは #pragma weak を無視して 警告メッセージを出します。

弱い identifier が定義されているときには、コンパイラーは #pragma weak を無視し、重大エラー・メッセージを出します。

  1. 以下はプラグマの #pragma weak identifier 形式の例です。
    // Begin Compilation Unit 1
    #include <stdio.h>
    extern int foo;
    #pragma weak foo
    
    int main()
    {
       int *ptr;
       ptr = &foo;
       if (ptr == 0)
          printf("foo has been assigned a value of 0¥n");
       else
          printf("foo was already defined¥n");
    }
    //End Compilation Unit 1
    
    // Begin Compilation Unit 2
    int foo = 1;
    // End Compilation Unit 2
    
           	
    Compilation Unit 1 だけがコンパイルされて実行可能ファイルを作成する場合、identifier foo が定義され、値 0 を割り当てられます。 実行からの出力は次のストリングになります: 「foo に値 0 が割り当てられました (foo has been assigned a value of 0)。」
  2. 以下はプラグマの #pragma weak identifier=identifier2 の形式の例です。
    //Begin Compilation Unit 
    extern "C" void printf(char *,...);
    
    void foo1(void)
    {
       printf("Just in function foo1()¥n");
    }
    
    
    #pragma weak _Z3foov = _Z4foo1v
    
    int main()
    {
       foo();
    }
    //End Compilation Unit