Sun Studio 12 Update 1: C++ ユーザーズガイド

B.2.18 #pragma weak


#pragma weak name1 [= name2]

weak を使用すると、弱い (weak) 大域シンボルを定義できます。このプラグマは主にソースファイルの中でライブラリを構築するために使用されます。リンカーは弱いシンボルを認識できなくてもエラーメッセージを出しません。

weak プラグマは、次の 2 つの書式でシンボルを指定できます。

B.2.18.1 #pragma weak name

#pragma weak name という書式の指令は、name を弱い (weak) シンボルに定義します。name のシンボル定義が見つからなくても、リンカーはエラーメッセージを生成しません。また、弱いシンボルの定義を複数見つけた場合でも、リンカーはエラーメッセージを生成しません。リンカーは単に最初に検出した定義を使用します。

プラグマ name の強い定義が存在しない場合、リンカーはシンボルの値を 0 にします。

次の指令は、ping を弱いシンボルに定義しています。ping という名前のシンボルの定義が見つからない場合でも、リンカーはエラーメッセージを生成しません。


#pragma weak ping

#pragma weak name1 = name2

#pragma weak name1 = name2 という書式の指令は、シンボル name1name2 への弱い参照として定義します。name1 がどこにも定義されていない場合、name1 の値は name2 の値になります。name1 が別の場所で定義されている場合、リンカーはその定義を使用し、name2 への弱い参照は無視します。次の指令では、bar がプログラムのどこかで定義されている場合、リンカーはすべての参照先を bar に設定します。そうでない場合、リンカーは bar への参照を foo にリンクします。


#pragma weak bar = foo

識別子書式では、name2 は現在のコンパイル単位内で宣言および定義しなければいけません。たとえば、次のようにします。


extern void bar(int) {...}
extern void _bar(int);
#pragma weak _bar=bar

文字列書式を使用する場合、シンボルはあらかじめ宣言されている必要はありません。次の例において、_barbar の両方が extern "C" である場合、その関数はあらかじめ宣言されている必要はありません。しかし、bar は同じオブジェクト内で定義されている必要があります。


extern "C" void bar(int) {...}
#pragma weak "_bar" = "bar"

関数の多重定義

識別子書式を使用するとき、プラグマのあるスコープ中には指定した名前を持つ関数は、1 つしか存在してはいけません。多重定義関数に識別子書式の #pragma weak を使おうとすると、エラーになります。たとえば、次のようにします。


int bar(int);
float bar(float);
#pragma weak bar        // error, ambiguous function name

このエラーを回避するには、文字列書式を使用します。例を次に示します。


int bar(int);
float bar(float);
#pragma weak "__1cDbar6Fi_i_" // make float bar(int) weak

詳細は、Solaris の『リンカーとライブラリ』を参照してください。