Sdílet prostřednictvím


init_seg

Konkrétní C++

Určuje oddíl klíčové slovo nebo kód, který ovlivňuje pořadí, ve které spouštěcí kód spuštěn.

#pragma init_seg({ compiler | lib | user | "section-name" [, func-name]} )

Poznámky

Význam těchto termínů segmentu a části jsou zaměnitelné v tomto tématu.

Inicializace globální statických objektů může zahrnovat spouštění kódu, a proto je nutné zadat klíčové slovo, které určuje, kdy jsou objekty budované.Je důležité zejména pro použití init_seg pragma v dynamických knihoven (DLL) nebo vyžadující inicializace knihovny.

Možnosti init_seg jsou záhlaví pragma:

  • Kompilátor
    Inicializace knihovny runtime Microsoft C vyhrazeny.Objekty v této skupině jsou vyrobeny první.

  • lib
    K dispozici pro inicializací výrobců knihovna tříd dodavatelů.Objekty v této skupině jsou konstruovány po těch označen jako kompilátoru , ale před všech ostatních.

  • uživatel
    K dispozici všem uživatelům.Objekty v této skupině jsou konstruovány jako poslední.

  • název oddílu
    Umožňuje explicitní specifikaci oddílu inicializace.Uživatelem zadané objekty název oddílu není implicitně vyrobeno; jejich adresy jsou však uváděny v části s názvem název oddílu.

    Název oddílu, které bude obsahovat ukazatele na pomocné funkce, které budou vytvářet globální objekty deklarované v modulu po pragma.

    Seznam názvů byste neměli používat při vytváření oddílu naleznete v tématu /SECTION.

  • název FUNC
    Určuje místo volat funkci atexit při ukončení programu.Pomocné funkce také volá atexit s ukazatel na objekt pro globální objekt.Pokud zadáte identifikátor funkce pragma formuláře,

    int __cdecl myexit (void (__cdecl *pf)(void))
    

    pak bude namísto C Runtime library volána funkce atexit.Umožňuje vytvořit seznam destruktory, které je třeba volat, pokud budete chtít zničit objekty.

Chcete-li odložit inicializace (například v knihovně DLL) můžete explicitně zadat název oddílu.Pro každý objekt statické musí zavolejte konstruktory.

Neexistují žádné uvozovek identifikátor atexit náhradní.

Objekty stále bude umístěna v oddílech, které jsou definovány jiné XXX_seg pragmas.

Objekty, které jsou deklarovány v modulu bude podle C Runtime automaticky inicializován.Musíte tento sami.

Ve výchozím nastavení init_seg oddíly jsou jen pro čtení.Pokud je název oddílu.CRT, kompilátor bude bez upozornění změnit atribut pouze pro čtení, i když je označena jako přečtená, zapsat.

Nelze zadat init_seg více než jednou v jednotce překlad.

I v případě, že objekt nemá konstruktor definovaný uživatelem, konstruktor není explicitně definována v kódu, kompilátor může generovat jednu (například svázat ukazatele v tabulce).Kód bude tudíž volání konstruktoru generovaných 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();
}
  

Viz také

Referenční dokumentace

Pragma směrnic a __Pragma klíčové slovo