__declspec(code_seg)

Microsoft 固有の仕様

宣言属性は code_seg 、関数またはクラス メンバー関数の .obj オブジェクト コードが格納されているファイル内の実行可能テキスト セグメントに名前を付けます。

構文

__declspec(code_seg("segname")) declarator

解説

__declspec(code_seg(...)) 属性では、メモリ内でそれぞれページングまたはロックできる個別の名前のセグメントにコードを格納できます。 この属性を使用して、インスタンス化されたテンプレートとコンパイラによって生成されたコードの格納場所を制御できます。

セグメントは、単位としてメモリに読み込まれるファイル内.objのデータの名前付きブロックです。 テキスト セグメントは、実行可能なコードが格納されるセグメントです。 セクションという用語はセグメントの同義語として使用されることがよくあります。

declarator が定義されているときに生成されるオブジェクト コードは、ナロー文字列リテラルである segname で指定されたテキスト セグメントに格納されます。 宣言で使用する前に、セクション プラグマで名前segnameを指定する必要はありません。 既定では、指定されていない code_seg 場合、オブジェクト コードは 、という名前 .textのセグメントに配置されます。 属性は code_seg 、既存 の #pragma code_seg ディレクティブをオーバーライドします。 code_segメンバー関数に適用された属性は、外側のクラスに適用されるすべてのcode_seg属性をオーバーライドします。

エンティティに属性がある code_seg 場合、同じエンティティのすべての宣言と定義に同じ code_seg 属性が必要です。 基底クラスに属性がある code_seg 場合、派生クラスには同じ属性が必要です。

属性が code_seg 名前空間スコープ関数またはメンバー関数に適用されると、その関数のオブジェクト コードが指定されたテキスト セグメントに配置されます。 この属性をクラスに適用すると、クラスのすべてのメンバー関数と入れ子になったクラス (コンパイラによって生成された特殊なメンバー関数を含む) が、指定されたセグメントに配置されます。 ローカルで定義されたクラス (メンバー関数本体で定義されているクラスなど) は、外側のスコープの属性を継承 code_seg しません。

属性が code_seg クラス テンプレートまたは関数テンプレートに適用されると、テンプレートのすべての暗黙的特殊化が指定されたセグメントに配置されます。 明示的または部分的な特殊化は、プライマリ テンプレートから属性を継承 code_seg しません。 特殊化に同じ属性または別 code_seg の属性を指定できます。 明示的な code_seg テンプレートのインスタンス化に属性を適用することはできません。

既定では、特殊なメンバー関数などのコンパイラによって生成されたコードがセグメントに .text 配置されます。 ディレクティブは #pragma code_seg 、この既定値をオーバーライドしません。 code_segクラス、クラス テンプレート、または関数テンプレートの属性を使用して、コンパイラによって生成されたコードを配置する場所を制御します。

ラムダは、外側のスコープから属性を継承 code_seg します。 ラムダのセグメントを指定するには、パラメーター宣言句の後、および変更可能または例外の指定、後続の戻り値の型指定、ラムダ本体の前に属性を適用 code_seg します。 詳細については、「ラムダ式の構文」を参照してください。 この例では、ラムダを PagedMem という名前のセグメントに定義しています。

auto Sqr = [](int t) __declspec(code_seg("PagedMem")) -> int { return t*t; };

特定のメンバー関数 (特に仮想メンバー関数) を異なるセグメントに格納するときには注意が必要です。 たとえば、基底クラス メソッドが非ページ セグメントに存在する場合に、ページ 分割されたセグメントに存在する派生クラスで仮想関数を定義するとします。 その他の基本クラス メソッドまたはユーザー コードでは、仮想メソッドを呼び出してもページ フォールトがトリガーされないと想定される場合があります。

この例では、暗黙的および明示的な code_seg テンプレートの特殊化が使用されている場合に、属性がセグメントの配置を制御する方法を示します。

// code_seg.cpp
// Compile: cl /EHsc /W4 code_seg.cpp

// Base template places object code in Segment_1 segment
template<class T>
class __declspec(code_seg("Segment_1")) Example
{
public:
   virtual void VirtualMemberFunction(T /*arg*/) {}
};

// bool specialization places code in default .text segment
template<>
class Example<bool>
{
public:
   virtual void VirtualMemberFunction(bool /*arg*/) {}
};

// int specialization places code in Segment_2 segment
template<>
class __declspec(code_seg("Segment_2")) Example<int>
{
public:
   virtual void VirtualMemberFunction(int /*arg*/) {}
};

// Compiler warns and ignores __declspec(code_seg("Segment_3"))
// in this explicit specialization
__declspec(code_seg("Segment_3")) Example<short>; // C4071

int main()
{
   // implicit double specialization uses base template's
   // __declspec(code_seg("Segment_1")) to place object code
   Example<double> doubleExample{};
   doubleExample.VirtualMemberFunction(3.14L);

   // bool specialization places object code in default .text segment
   Example<bool> boolExample{};
   boolExample.VirtualMemberFunction(true);

   // int specialization uses __declspec(code_seg("Segment_2"))
   // to place object code
   Example<int> intExample{};
   intExample.VirtualMemberFunction(42);
}

Microsoft 固有の仕様はここまで

関連項目

__declspec
キーワード