__declspec(code_seg)
Specyficzne dla firmy Microsoft
Atrybut code_seg
deklaracji nazywa segment tekstu wykonywalnego w .obj
pliku, w którym jest przechowywany kod obiektu dla funkcji lub funkcji składowych klasy.
Składnia
__declspec(code_seg("
segname
"))
declarator
Uwagi
Atrybut __declspec(code_seg(...))
umożliwia umieszczanie kodu w osobnych nazwanych segmentach, które mogą być stronicowane lub zablokowane osobno w pamięci. Możesz używać tego atrybutu, aby kontrolować rozmieszczenie wystąpień szablonów i kodu generowanego przez kompilator.
Segment to nazwany blok danych w .obj
pliku, który jest ładowany do pamięci jako jednostka. Segment tekstowy to segment zawierający kod wykonywalny. Termin sekcja jest często używana zamiennie z segmentem.
Kod obiektu generowany podczas declarator
definiowania jest umieszczany w segmencie tekstowym określonym przez segname
element , który jest literałem wąskim ciągu. Nazwa segname
nie musi być określona w sekcji pragma, zanim będzie można jej użyć w deklaracji. Domyślnie, jeśli nie code_seg
jest określony, kod obiektu jest umieszczany w segmencie o nazwie .text
. Atrybut zastępuje dowolną code_seg
istniejącą dyrektywę #pragma code_seg . Atrybut code_seg
zastosowany do funkcji składowej zastępuje dowolny code_seg
atrybut zastosowany do otaczającej klasy.
Jeśli jednostka ma code_seg
atrybut, wszystkie deklaracje i definicje tej samej jednostki muszą mieć identyczne code_seg
atrybuty. Jeśli klasa bazowa ma code_seg
atrybut, klasy pochodne muszą mieć ten sam atrybut.
code_seg
Gdy atrybut jest stosowany do funkcji zakresu przestrzeni nazw lub funkcji składowej, kod obiektu dla tej funkcji jest umieszczany w określonym segmencie tekstowym. Po zastosowaniu tego atrybutu do klasy wszystkie funkcje składowe klas i klas zagnieżdżonych — w tym specjalne funkcje składowe generowane przez kompilator — są umieszczane w określonym segmencie. Klasy zdefiniowane lokalnie — na przykład klasy zdefiniowane w treści funkcji składowej — nie dziedziczą code_seg
atrybutu otaczającego zakresu.
code_seg
Po zastosowaniu atrybutu do szablonu klasy lub szablonu funkcji wszystkie niejawne specjalizacje szablonu są umieszczane w określonym segmencie. Jawne lub częściowe specjalizacje nie dziedziczą code_seg
atrybutu z szablonu podstawowego. Możesz określić ten sam lub inny code_seg
atrybut specjalizacji. Atrybutu code_seg
nie można zastosować do wystąpienia jawnego szablonu.
Domyślnie kod generowany przez kompilator, taki jak specjalna funkcja składowa, jest umieszczany w segmencie .text
. Dyrektywa #pragma code_seg
nie zastępuje tej wartości domyślnej. Użyj atrybutu code_seg
w klasie, szablonie klasy lub szablonie funkcji, aby kontrolować miejsce umieszczenia kodu generowanego przez kompilator.
Lambdy dziedziczą code_seg
atrybuty z otaczającego zakresu. Aby określić segment dla lambda, zastosuj code_seg
atrybut po klauzuli deklaracji parametrów i przed dowolną specyfikacją modyfikowalnego lub wyjątku, dowolną specyfikacją zwracanego typu końcowego i treścią lambda. Aby uzyskać więcej informacji, zobacz Składnia wyrażeń lambda. Ten przykład definiuje lambdę w segmencie o nazwie PagedMem:
auto Sqr = [](int t) __declspec(code_seg("PagedMem")) -> int { return t*t; };
Należy zachować ostrożność przy umieszczaniu określonych funkcji elementów członkowskich — zwłaszcza wirtualnych funkcji elementów członkowskich — w różnych segmentach. Załóżmy, że definiujesz funkcję wirtualną w klasie pochodnej, która znajduje się w segmencie stronicowanym, gdy metoda klasy bazowej znajduje się w segmencie niestronicowanym. Inne metody klasy bazowej lub kod użytkownika mogą zakładać, że wywołanie metody wirtualnej nie spowoduje wyzwolenia błędu strony.
Przykład
W tym przykładzie pokazano, jak code_seg
atrybut kontroluje umieszczanie segmentów w przypadku użycia niejawnej i jawnej specjalizacji szablonu:
// 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);
}
END Microsoft Specific
Zobacz też
Opinia
https://aka.ms/ContentUserFeedback.
Dostępne już wkrótce: W 2024 r. będziemy stopniowo wycofywać zgłoszenia z serwisu GitHub jako mechanizm przesyłania opinii na temat zawartości i zastępować go nowym systemem opinii. Aby uzyskać więcej informacji, sprawdź:Prześlij i wyświetl opinię dla