init_seg

C++ specifica

Specifica una parola chiave o una sezione di codice che influiscono sull'ordine in cui il codice di avvio viene eseguito.

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

Note

Il significato dei termini segmento e sezione essere intercambiabile in questo argomento.

Poiché l'inizializzazione degli oggetti statici globali può includere codice in esecuzione, è necessario specificare una parola chiave che definisce quando gli oggetti devono essere creati.è particolarmente importante utilizzare init_seg pragma in librerie a (DLLs) collegamento dinamico o nelle librerie che richiedono l'inizializzazione.

Le opzioni a init_seg il pragma è:

  • compilatore
    Riservato all'inizializzazione della libreria di runtime del linguaggio C Microsoft.Gli oggetti in questo gruppo vengono costruiti per primo.

  • lib
    Disponibile per le inizializzazioni di terze parti dei fornitori della libreria di classi.Gli oggetti in questo gruppo analoghi a quelli contrassegnati come compilatore ma prima di qualsiasi altro.

  • utente
    disponibile a qualsiasi utente.Gli oggetti in questo gruppo vengono costruiti per ultima.

  • nome della sezione
    Consente la specifica esplicita della sezione di inizializzazione.Oggetti in un oggetto definito dall'utente nome della sezione in modo implicito non vengono costruiti; tuttavia, gli indirizzi vengono inseriti nella sezione denominata da nome della sezione.

    Il nome della sezione fornita conterrà i puntatori a funzioni di supporto che costruiranno gli oggetti globali dichiarati in tale modulo dopo il pragma.

    Per un elenco di nomi che non è necessario utilizzare durante la creazione di una sezione, vedere /SECTION.

  • funzionale-nome
    specifica una funzione da chiamare invece di atexit al termine del programma.Chiamate a questa funzione di supporto inoltre atexit con un puntatore al distruttore per l'oggetto globale.Se si specifica un identificatore di funzione nel pragma del form,

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

    quindi la funzione venga chiamata anziché la libreria di runtime del linguaggio C atexit.Ciò consente di compilare un elenco dei distruttori che dovranno essere chiamati quando si è pronti per eliminare gli oggetti.

Se è necessario rinviare l'inizializzazione (ad esempio, in una DLL) è possibile scegliere di specificare il nome della sezione in modo esplicito.È quindi necessario chiamare i costruttori per ogni oggetto statico.

Non esistono virgolette intorno all'identificatore per atexit sostituzione.

Gli oggetti verranno comunque inseriti in quelle definite dagli altri pragma di XXX_seg.

Gli oggetti dichiarati nel modulo automaticamente non verranno inizializzati dal runtime del linguaggio C.Sarà necessario apportare che manualmente.

per impostazione predefinita, init_seg le sezioni sono di sola lettura.Se il nome della sezione .CRT è, il compilatore verrà automaticamente l'attributo in sola lettura, anche se è contrassegnato come lettura, scrittura.

Non è possibile specificare init_seg più volte in un'unità di conversione.

Anche se l'oggetto non ha un costruttore definito dall'utente, un costruttore non definito in modo esplicito nel codice, il compilatore può generare uno (ad esempio l'associazione puntatori di v-tabella).Di conseguenza, il codice deve chiamare il costruttore generato dal compilatore.

Esempio

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

Vedere anche

Riferimenti

Direttive pragma e la parola chiave di __Pragma