__declspec(code_seg)
Блок, относящийся только к системам Майкрософт
code_seg
Атрибут объявления называет исполняемый текстовый сегмент в .obj
файле, в котором хранится код объекта для функций-членов функции или класса.
Синтаксис
__declspec(code_seg("
segname
"))
declarator
Замечания
Атрибут __declspec(code_seg(...))
позволяет помещать код в различные именованные сегменты, которые можно выгружать или блокировать в памяти по отдельности. Можно использовать этот атрибут для управления размещением шаблонов с созданными экземплярами и кода, созданного компилятором.
Сегмент — это именованный блок данных в файле, который загружается в .obj
память в виде единицы. Сегмент текста — это сегмент , содержащий исполняемый код. Раздел терминов часто используется взаимозаменяемо с сегментом.
Объектный код, создаваемый при определении declarator
, помещается в сегмент текста, указанный segname
, а это узкий строковый литерал. Имя segname
не должно быть указано в разделе pragma, прежде чем его можно будет использовать в объявлении. По умолчанию, если не 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);
}
Завершение блока, относящегося только к системам Майкрософт
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по