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

4.1 リンカースコープ

次の宣言指定子を、外部シンボルの宣言や定義の制約のために使用します。静的なアーカイブやオブジェクトファイルに対して指定したスコープは、共有ライブラリや実行可能ファイルにリンクされるまで、適用されません。しかしながら、コンパイラは、与えられたリンカースコープ指定子に応じたいくつかの最適化を行うことができます。

これらの指示子を使うと、リンカースコープのマップファイルは使用しなくてすみます。 -xldscope をコマンド行で指定することによって、変数スコープのデフォルト設定を制御することもできます。

詳細は、「A.2.136 -xldscope={v}」を参照してください。

表 4–1 リンカースコープ宣言指定子

値 

意味 

__global

シンボル定義には大域リンカースコープとなります。これは、もっとも限定的でないリンカースコープです。シンボル参照はすべて、そのシンボルが定義されている最初の動的ロードモジュール内の定義と結合します。このリンカースコープは、extern シンボルの現在のリンカースコープです。

__symbolic

シンボル定義は、シンボリックリンカースコープとなります。これは、大域リンカースコープより限定的なリンカースコープです。リンク対象の動的ロードモジュール内からのシンボルへの参照はすべて、そのモジュール内に定義されているシンボルと結合します。モジュールの外側では、シンボルは大域と同じです。このリンカースコープはリンカーオプション -Bsymbolic に対応します。C++ ライブラリでは -Bsymbolic を使用できませんが、__symbolic 指定子は問題なく使用できます。リンカーの詳細については、ld(1) を参照してください。

__hidden

シンボル定義は、隠蔽リンカースコープとなります。隠蔽リンカースコープは、シンボリックリンカースコープや大域リンカースコープよりも制限されたリンカースコープです。動的ロードモジュール内の参照はすべて、そのモジュール内の定義に結合します。シンボルはモジュールの外側では認識されません。

より限定的な指定子を使ってシンボル定義を宣言しなおすことはできますが、より限定的でない指定子を使って宣言しなおすことはできません。シンボルは一度定義したら、異なる指示子で宣言することはできません。

__global はもっとも制限の少ないスコープです。__symbolic はより制限されたスコープです。__hidden はもっとも制限の多いスコープです。

仮想関数の宣言は仮想テーブルの構造と解釈に影響を及ぼすので、あらゆる仮想関数は、クラス定義を含んでいるあらゆるコンパイル単位から認識される必要があります。

C++ クラスでは、仮想テーブルや実行時型情報といった暗黙の情報の生成が必要と なることがあるため、 構造体、クラス、および共用体の宣言と定義にリンカースコープ指定子を適用できるようになっています。その場合、指定子は、構造体、クラス、または共用体キーワードの直後に置きます。こういったアプリケーションでは、すべての暗黙のメンバーに対して 1 つのリンカースコーピングが適用されます。

4.1.1 Microsoft Windows との互換性

動的ライブラリに関して 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++ で同じ結果を得ることができます。