#pragma weak ディレクティブを実行すると、シンボルの定義が検索されないときや、リンク中に複数のシンボルが定義されていることが発見されたときに、リンケージ・エディターはエラー・メッセージを発行できません。
>>-#--pragma--weak--identifier--+----------------+------------->< '-=--identifier2-'
このプラグマは関数とともに使用することを基本条件として設計されていますが、ほとんどのデータ・オブジェクトに対しても有効に機能します。
このプラグマは、未初期化状態のグローバル・データと共に、あるいは実行可能ファイルにエクスポートされる共用ライブラリー・データ・オブジェクトと共には使用しないようにしてください。
ダイナミック・リンカーはコマンド行に最初に表示されるオブジェクトに定義を使用します。そのため、オブジェクト・ファイルがリンカーに示される順序は重要です。
プログラム・ソースには、2 つの形式の #pragma weak を指定できます。
- #pragma weak ID
- この形式のプラグマは、identifier を弱いグローバル・シンボルとして定義します。identifier に対する参照では定義された ID 値が使用され、定義されていない場合、identifier には値 0 が割り当てられます。
Identifier が #pragma weak identifier と同じコンパイル単位で定義されている場合、identifier は weak 定義として処理されます。identifier を使用も宣言もしないコンパイル単位に #pragma weak が存在する場合、プラグマは受け入れられても無視されます。
identifier が C++ リンケージを持つ関数を指示するときは、identifier はその関数の C++ マングル名を使用して指定しなければなりません。また、C++ 関数がテンプレート関数である場合、このテンプレート関数を明示的にインスタンス化する必要があります。
- #pragma weak identifier=identifier2
- この形式のプラグマは、identifier を弱いグローバル・シンボルとして定義します。identifier を参照するときは、identifier2 の値を使用します。
identifier2 はメンバー関数にできません。
identifier は #pragma weak と同じコンパイル単位に宣言できることとできないことがありますが、このコンパイル単位には定義しないでください。
identifier がこのコンパイル単位に宣言されると、identifier の宣言は identifier2 の宣言と互換性がなければなりません。例えば identifier2 が関数のときは、identifier は identifier2 と同じ戻りまたは引き数の型がなければなりません。
identifier2 は #pragma weak と同じコンパイル単位で宣言されていなければなりません。
identifier2 が C++ リンケージを持つ関数を指示するときは、identifier と identifier2 はその関数のマングル名を使用して指定しなければなりません。 C++ 関数がテンプレート関数である場合、このテンプレート関数を明示的にインスタンス化する必要があります。
以下の場合、コンパイラーは #pragma weak を無視して警告メッセージを出します。
- 指定された identifier2 がコンパイル単位に定義されていない。
- 指定された identifier2 がメンバー関数である。
- identifier は宣言されているが、その型が指定された identifier2 の型と互換性がない。
コンパイラーは #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 のみがコンパイルされる場合、 ID 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