Partilhar via


init_seg pragma

específicos do C++

Especifica uma palavra-chave ou seção de código que afeta a ordem na qual o código de inicialização é executado.

Sintaxe

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

Comentários

Os termos segmento e seção têm o mesmo significado neste artigo.

Como o código às vezes é necessário para inicializar objetos estáticos globais, você deve especificar quando construir os objetos. Em particular, é importante usar o init_segpragma em bibliotecas de vínculo dinâmico (DLLs) ou em bibliotecas que exigem inicialização.

As opções para o init_segpragma são:

compiler
Reservado para inicialização da biblioteca de tempo de execução do Microsoft C. Os objetos deste grupo são construídos primeiro.

lib
Disponível para inicializações de fornecedores de bibliotecas de classes de terceiros. Os objetos deste grupo são construídos depois dos marcados como compiler, mas antes de quaisquer outros.

user
Disponível para qualquer utilizador. Os objetos deste grupo são construídos por último.

nome da seção
Permite a especificação explícita da seção de inicialização. Os objetos em um de nome de seção especificado pelo usuário não são construídos implicitamente. No entanto, seus endereços são colocados na seção nomeada por nome da seção.

O de nome de seção que você fornecer conterá ponteiros para funções auxiliares que construirão os objetos globais declarados após a nesse módulo.

Para obter uma lista de nomes que você não deve usar ao criar uma seção, consulte /SECTION.

func-name
Especifica uma função a ser chamada no lugar de atexit quando o programa é encerrado. Essa função auxiliar também chama atexit com um ponteiro para o destruidor do objeto global. Se você especificar um identificador de função na pragma do formulário,

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

em seguida, sua função será chamada em vez do atexitda biblioteca de tempo de execução C. Ele permite que você construa uma lista dos destruidores para chamar quando estiver pronto para destruir os objetos.

Se você precisar adiar a inicialização (por exemplo, em uma DLL), você pode optar por especificar o nome da seção explicitamente. Seu código deve então chamar os construtores para cada objeto estático.

Não há aspas em torno do identificador para o atexit substituição.

Seus objetos ainda serão colocados nas seções definidas pelas outras diretivas XXX_segpragma.

Os objetos declarados no módulo não são inicializados automaticamente pelo tempo de execução C. Seu código tem que fazer a inicialização.

Por padrão, init_seg seções são somente leitura. Se o nome da seção for .CRT, o compilador silenciosamente alterará o atributo para somente leitura, mesmo que esteja marcado como leitura, gravação.

Não é possível especificar init_seg mais de uma vez em uma unidade de tradução.

Mesmo que seu objeto não tenha um construtor definido pelo usuário, um explicitamente definido no código, o compilador pode gerar um para você. Por exemplo, ele pode criar um para vincular ponteiros v-table. Quando necessário, seu código chama o construtor gerado pelo compilador.

Exemplo

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

Ver também

diretivas Pragma e as palavras-chave __pragma e _Pragma