Udostępnij za pośrednictwem


init_seg pragma

Specyficzne dla języka C++

Określa słowo kluczowe lub sekcję kodu, która ma wpływ na kolejność wykonywania kodu uruchamiania.

Składnia

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

Uwagi

Terminy segment i sekcja mają takie samo znaczenie w tym artykule.

Ponieważ kod jest czasami wymagany do inicjowania globalnych obiektów statycznych, należy określić, kiedy utworzyć obiekty. W szczególności ważne jest, aby używać bibliotek linku init_segpragma dynamicznego (DLL) lub w bibliotekach wymagających inicjowania.

Dostępne opcje init_segpragma to:

compiler
Zarezerwowane dla inicjowania biblioteki uruchomieniowej Microsoft C. Obiekty w tej grupie są najpierw konstruowane.

lib
Dostępne dla inicjalizacji biblioteki innych firm. Obiekty w tej grupie są konstruowane po tych oznaczonych jako compiler, ale przed innymi.

user
Dostępny dla dowolnego użytkownika. Obiekty w tej grupie są konstruowane jako ostatnie.

nazwa-sekcji
Umożliwia jawną specyfikację sekcji inicjowania. Obiekty w nazwie sekcji określonej przez użytkownika nie są niejawnie konstruowane. Jednak ich adresy są umieszczane w sekcji o nazwie według nazwy sekcji.

Podana nazwa sekcji będzie zawierać wskaźniki do funkcji pomocnika, które skonstruują obiekty globalne zadeklarowane po pragma w tym module.

Aby uzyskać listę nazw, których nie należy używać podczas tworzenia sekcji, zobacz /SECTION.

func-name
Określa funkcję, która ma być wywoływana zamiast atexit , gdy program kończy działanie. Ta funkcja pomocnika wywołuje atexit również wskaźnik do destruktora dla obiektu globalnego. Jeśli określisz identyfikator funkcji w pragma formularzu,

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

następnie funkcja zostanie wywołana zamiast biblioteki środowiska uruchomieniowego atexitjęzyka C . Umożliwia utworzenie listy destruktorów do wywołania, gdy wszystko będzie gotowe do zniszczenia obiektów.

Jeśli musisz odroczyć inicjowanie (na przykład w dll), możesz jawnie określić nazwę sekcji. Kod musi następnie wywoływać konstruktory dla każdego obiektu statycznego.

Nie ma cudzysłowów wokół identyfikatora zamiany atexit .

Obiekty będą nadal umieszczane w sekcjach zdefiniowanych przez inne XXX_segpragma dyrektywy.

Obiekty zadeklarowane w module nie są automatycznie inicjowane przez czas wykonywania języka C. Kod musi wykonać inicjowanie.

Domyślnie init_seg sekcje są tylko do odczytu. Jeśli nazwa sekcji to .CRT, kompilator dyskretnie zmienia atrybut tylko do odczytu, nawet jeśli jest oznaczony jako odczyt, zapis.

Nie można określić init_seg więcej niż raz w jednostce tłumaczenia.

Nawet jeśli obiekt nie ma konstruktora zdefiniowanego przez użytkownika, jeden jawnie zdefiniowany w kodzie, kompilator może wygenerować go dla Ciebie. Może na przykład utworzyć jeden z nich, aby powiązać wskaźniki tabeli wirtualnej. W razie potrzeby kod wywołuje konstruktor wygenerowany przez kompilator.

Przykład

// 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()

Zobacz też

Pragmadyrektywy i __pragma słowa kluczowe i _Pragma