次の宣言指定子を、外部シンボルの宣言や定義の制約のために使用します。静的なアーカイブやオブジェクトファイルに対して指定したスコープは、共有ライブラリや実行可能ファイルにリンクされるまで、適用されません。しかしながら、コンパイラは、与えられたリンカースコープ指定子に応じたいくつかの最適化を行うことができます。
これらの指示子を使うと、リンカースコープのマップファイルは使用しなくてすみます。 -xldscope をコマンド行で指定することによって、変数スコープのデフォルト設定を制御することもできます。
詳細は、「A.2.136 -xldscope={v}」を参照してください。
表 4–1 リンカースコープ宣言指定子
より限定的な指定子を使ってシンボル定義を宣言しなおすことはできますが、より限定的でない指定子を使って宣言しなおすことはできません。シンボルは一度定義したら、異なる指示子で宣言することはできません。
__global はもっとも制限の少ないスコープです。__symbolic はより制限されたスコープです。__hidden はもっとも制限の多いスコープです。
仮想関数の宣言は仮想テーブルの構造と解釈に影響を及ぼすので、あらゆる仮想関数は、クラス定義を含んでいるあらゆるコンパイル単位から認識される必要があります。
C++ クラスでは、仮想テーブルや実行時型情報といった暗黙の情報の生成が必要と なることがあるため、 構造体、クラス、および共用体の宣言と定義にリンカースコープ指定子を適用できるようになっています。その場合、指定子は、構造体、クラス、または共用体キーワードの直後に置きます。こういったアプリケーションでは、すべての暗黙のメンバーに対して 1 つのリンカースコーピングが適用されます。
動的ライブラリに関して Microsoft Visual C++ (MSVC++) に含まれる類似のスコープ機能との互換性を保つため、次の構文もサポートされています。
__declspec(dllexport) は __symbolic と同一です。 |
__declspec(dllimport) は __global と同一です。 |
Sun C++ でこの構文の利点を活用するには、-xldscope=hidden オプションを CC コマンド行に追加するべきです。結果は、MSVC++ を使用する場合と比較可能なものになります。MSVC++ を使用する場合は、定義ではなく外部シンボルの宣言のみに関して __declspec(dllimport) が使用されることが想定されます。次に例を示します。
__declspec(dllimport) int foo(); // OK __declspec(dllimport) int bar() { ... } // not OK |
MSVC++ は、定義に対する dllimport の許容が緩やかであり、Sun C++ を使用する場合の結果と異なります。特に、Sun C++ で定義に対して dllimport を使用する場合の結果は、シンボルがシンボリックリンケージではなくグローバルリンケージを持つことになります。Microsoft Windows 上の動的ライブラリは、シンボルのグローバルリンケージをサポートしません。この問題が発生している場合は、定義に対して dllimport ではなく dllexport を使用するようにソースコードを変更できます。その後、MSVC++ と Sun C++ で同じ結果を得ることができます。