init_seg

específico de C++

Especifica una palabra clave o una sección de código que afectan al orden en que se ejecuta el código de inicio.

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

Comentarios

El significado de los términos segmento y sección se puede cambiar en este tema.

Dado que la inicialización de objetos estáticos globales puede implicar ejecutando código, debe especificar una palabra clave que define cuándo los objetos deben ser construidos.Es particularmente importante utilizar la directiva pragma de init_seg en bibliotecas de (DLLs) vínculos dinámicos o bibliotecas que requieren inicialización.

Las opciones al pragma de init_seg son:

  • compilador
    Reservado para la inicialización de la biblioteca en tiempo de ejecución de Microsoft c.Los objetos de este grupo se construyen primero.

  • lib
    Disponibles para las inicializaciones de los proveedores de terceros de biblioteca de clases.Los objetos de este grupo se construyen después de aquellos marcados como compilador pero antes de cualquier otro.

  • usuario
    Disponibles para cualquier usuario.Los objetos de este grupo se construyen por última vez.

  • nombre de sección
    Permite la especificación explícita de la sección de inicialización.Los objetos de un nombre de sección definido por el usuario no se construyen implícita; sin embargo, configura sus direcciones en la sección denominada por el nombre de sección.

    El nombre de sección que asigna contendrá punteros a funciones auxiliares que construyan a partir de objetos globales declarados en ese módulo después de pragma.

    Para obtener una lista de nombres que no se debe utilizar cuando crea una sección, vea /SECTION.

  • funcional-nombre
    Especifica una función que se llama en lugar de atexit cuando los resultados del programa.Esta función auxiliar también llama a atexit con un puntero al destructor del objeto global.Si especifica un identificador de función en pragma del formulario,

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

    a la función se denominaría en lugar de atexitde la biblioteca en tiempo de ejecución de C.Esto permite compilar una lista de los destructores que deberán llamar cuando esté preparado para destruir los objetos.

Si necesita diferir la inicialización (por ejemplo, en una DLL) puede elegir para especificar el nombre de sección explícitamente.Debe llamar a los constructores de cada objeto estático.

No hay comillas alrededor del reemplazo de atexit .

Los objetos todavía se colocarán en las secciones definido por los demás pragmas de XXX_seg.

Los objetos que se declaran en el módulo automáticamente no se inicializarán por el tiempo de ejecución de C.Necesitará hacer que usted mismo.

De forma predeterminada, las secciones de init_seg son de sólo lectura.Si el nombre de sección es .CRT, el compilador cambiará automáticamente el atributo en readonly, incluso si se marca leído, escriba.

No puede especificar init_seg más de una vez en una unidad de traducción.

Incluso si el objeto no tiene un constructor definido por el usuario, un constructor no definidos explícitamente en el código, el compilador puede generar uno (por ejemplo enlazar punteros a v-tabla).Por consiguiente, el código tendrá que llamar al constructor generado por el compilador.

Ejemplo

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

Vea también

Referencia

Directivas de pragma y la palabra clave de __Pragma