init_seg
pragma
Specifické pro C++
Určuje klíčové slovo nebo oddíl kódu, který má vliv na pořadí, ve kterém se spouští spouštěcí kód.
Syntaxe
#pragma init_seg(
{compiler
| |lib
user
| "section-name" [,
func-name ] })
Poznámky
Segment termínů a oddíl mají stejný význam v tomto článku.
Vzhledem k tomu, že kód je někdy nutný k inicializaci globálních statických objektů, je nutné určit, kdy se mají objekty sestavit. Zejména je důležité používat init_seg
pragma knihovny dynamického propojení (DLL) nebo knihovny, které vyžadují inicializaci.
init_seg
pragma Možnosti:
compiler
Vyhrazeno pro inicializaci knihovny runtime Microsoft C. Objekty v této skupině se vytvářejí jako první.
lib
K dispozici pro inicializace dodavatelů knihovny tříd třetích stran. Objekty v této skupině jsou sestaveny za objekty označené jako compiler
, ale před ostatními.
user
K dispozici pro libovolného uživatele. Objekty v této skupině jsou sestaveny jako poslední.
section-name
Umožňuje explicitní specifikaci oddílu inicializace. Objekty v názvu oddílu zadané uživatelem se implicitně nevykonstruují. Jejich adresy se ale umístí do oddílu pojmenovaného podle názvu oddílu.
Zadaný název oddílu bude obsahovat ukazatele na pomocné funkce, které vytvoří globální objekty deklarované za modulem pragma v tomto modulu.
Seznam názvů, které byste neměli používat při vytváření oddílu, najdete v tématu /SECTION
.
func-name
Určuje funkci, která se má volat místo atexit
ukončení programu. Tato pomocná funkce také volá atexit
ukazatel na destruktoru globálního objektu. Pokud zadáte identifikátor funkce ve pragma formuláři,
int __cdecl myexit (void (__cdecl *pf)(void))
funkce bude volána místo knihovny runtime jazyka atexit
C . Umožňuje vytvořit seznam destruktorů, které se mají volat, když jste připraveni zničit objekty.
Pokud potřebujete odložit inicializaci (například v knihovně DLL), můžete určit název oddílu explicitně. Kód pak musí volat konstruktory pro každý statický objekt.
Identifikátor nahrazení atexit
neobsahuje žádné uvozovky.
Objekty budou stále umístěny v oddílech definovaných jinými XXX_seg
pragma direktivami.
Objekty deklarované v modulu nejsou automaticky inicializovány za běhu jazyka C. Kód musí provést inicializaci.
Ve výchozím nastavení init_seg
jsou oddíly jen pro čtení. Pokud je .CRT
název oddílu , kompilátor bezobslužně změní atribut jen pro čtení, i když je označený jako čtení, zápis.
V jednotce překladu nemůžete zadat init_seg
více než jednou.
I když objekt nemá uživatelem definovaný konstruktor, jeden explicitně definovaný v kódu, může kompilátor vygenerovat ho za vás. Může například vytvořit jednu pro vytvoření vazby ukazatelů v-tabulky. V případě potřeby váš kód volá konstruktor vygenerovaný kompilátorem.
Příklad
// pragma_directive_init_seg.cpp
#include <stdio.h>
#pragma warning(disable : 4075)
typedef void (__cdecl *PF)(void);
int cxpf = 0; // number of destructors we need to call
PF pfx[200]; // pointers to destructors.
int myexit (PF pf) {
pfx[cxpf++] = pf;
return 0;
}
struct A {
A() { puts("A()"); }
~A() { puts("~A()"); }
};
// ctor & dtor called by CRT startup code
// because this is before the pragma init_seg
A aaaa;
// The order here is important.
// Section names must be 8 characters or less.
// The sections with the same name before the $
// are merged into one section. The order that
// they are merged is determined by sorting
// the characters after the $.
// InitSegStart and InitSegEnd are used to set
// boundaries so we can find the real functions
// that we need to call for initialization.
#pragma section(".mine$a", read)
__declspec(allocate(".mine$a")) const PF InitSegStart = (PF)1;
#pragma section(".mine$z",read)
__declspec(allocate(".mine$z")) const PF InitSegEnd = (PF)1;
// The comparison for 0 is important.
// For now, each section is 256 bytes. When they
// are merged, they are padded with zeros. You
// can't depend on the section being 256 bytes, but
// you can depend on it being padded with zeros.
void InitializeObjects () {
const PF *x = &InitSegStart;
for (++x ; x < &InitSegEnd ; ++x)
if (*x) (*x)();
}
void DestroyObjects () {
while (cxpf>0) {
--cxpf;
(pfx[cxpf])();
}
}
// by default, goes into a read only section
#pragma init_seg(".mine$m", myexit)
A bbbb;
A cccc;
int main () {
InitializeObjects();
DestroyObjects();
}
A()
A()
A()
~A()
~A()
~A()