__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 固有の仕様はここまで
関連項目
フィードバック
https://aka.ms/ContentUserFeedback」を参照してください。
以下は間もなく提供いたします。2024 年を通じて、コンテンツのフィードバック メカニズムとして GitHub の issue を段階的に廃止し、新しいフィードバック システムに置き換えます。 詳細については、「フィードバックの送信と表示