#pragma weak ディレクティブを実行すると、シンボルの定義が検出されないときやリンク中にシンボルが複数回定義されていることを検出したときに、リンケージ・エディターがエラー・メッセージを発行するのを阻止します。
>>-#--pragma--weak--identifier--+----------------+------------->< '-=--identifier2-'
このプラグマは関数とともに使用することを基本条件として設計されていますが、 ほとんどのデータ・オブジェクトに対しても有効に機能します。
このプラグマは初期化されていないグローバル・データや、実行可能ファイルにエクスポートされる共用ライブラリー・データ・オブジェクトと共に使用しないでください。
ダイナミック・リンカーはコマンド行に最初に表示されるオブジェクトに 定義を使用します。 そのため、オブジェクト・ファイルがリンカーに 示される順序は重要です。
プログラム・ソースには、2 つの形式の #pragma weak を 指定できます。
Identifier が #pragma weak identifier と同じコンパイル単位に定義されている場合、identifier は弱い定義として扱われます。identifier を使用も宣言もしていないコンパイル単位に #pragma weak が存在する場合、プラグマは受け入れられますが無視されます。
identifier が C++ リンケージを持つ関数を指示するとき は、identifier はその関数の C++ マングル名を使用して 指定しなければなりません。 また、C++ 関数がテンプレート関数の場合は、明示的にテンプレート関数のインスタンスを生成する必要があります。
identifier2 はメンバー関数にできません。
identifier は #pragma weak と同じコンパイル単位で宣言できる場合とできない場合がありますが、このコンパイル単位には定義しないでください。
identifier がこのコンパイル単位で宣言される場合、identifier の宣言は identifier2 の宣言と互換性がなければなりません。 例えば、identifier2 が関数の場合、identifier は identifier2 と同じ戻りの型および引数の型を持っている必要があります。
identifier2 は #pragma weak と同じコンパイル単位で宣言されていなければなりません。
identifier2 が C++ リンケージを持つ関数を示す場合は、その関数のマングル名を使用して identifier と identifier2 の名前を指定する必要があります。C++ 関数がテンプレート関数の場合は、明示的にテンプレート関数のインスタンスを生成する必要があります。
以下の場合、コンパイラーは #pragma weak を無視して 警告メッセージを出します。
弱い identifier が定義されているときには、コンパイラーは #pragma weak を無視し、重大エラー・メッセージを出します。
// 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 2Compilation Unit 1 だけがコンパイルされて実行可能ファイルを作成する場合、identifier foo が定義され、値 0 を割り当てられます。 実行からの出力は次のストリングになります: 「foo に値 0 が割り当てられました (foo has been assigned a value of 0)。」
//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