init_seg

Específico do C++

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

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

Comentários

O significado dos termos segmento e seção são intercambiáveis neste tópico.

Como a inicialização de objetos estáticos globais pode envolver a execução do código, você deve especificar uma palavra-chave que define quando os objetos devem ser construído.Ele é particularmente importante usar o init_seg pragma em bibliotecas de vínculo dinâmico (DLLs) ou bibliotecas que exigem a inicialização.

As opções para o init_seg pragma são:

  • compilador
    Reservado para a inicialização do Microsoft C Runtime library.Objetos desse grupo são construídos pela primeira vez.

  • lib
    Disponível para inicializações de fornecedores de biblioteca de classes de terceiros.Objetos desse grupo são construídos após os marcados como compilador , mas antes de quaisquer outros.

  • usuário
    Disponível para qualquer usuário.Objetos desse grupo são construídos pela última vez.

  • nome da seção
    Permite a especificação explícita da seção de inicialização.Objetos em um especificado pelo usuário nome da seção não são construídas implicitamente; No entanto, os endereços são colocados na seção denominada pela nome da seção.

    Contém ponteiros para funções auxiliares que construção os objetos globais declarados neste módulo, após o pragma você dar o nome da seção.

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

  • nome-do-func
    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 no pragma do formulário,

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

    e sua função será chamada em vez da biblioteca tempo de execução c atexit.Isso permite que você crie uma lista dos destrutores que precisarão ser chamado quando estiver pronto para destruir os objetos.

Caso você precise adiar a inicialização (por exemplo, em uma DLL), você pode optar por especificar explicitamente o nome da seção.Em seguida, você deve chamar os construtores para cada objeto estático.

Não há nenhum o identificador entre aspas o atexit substituição.

Os objetos ainda serão colocados nas seções definidas por outros pragmas de XXX_seg.

Os objetos que são declarados no módulo não serão inicializados automaticamente pelo tempo de execução C.Você precisará fazer essa sozinho.

Por padrão, init_seg seções são somente leitura.Se o nome da seção.CRT, o compilador silenciosamente alterará o atributo de somente leitura, mesmo se ele está marcado como leitura, gravação.

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

Mesmo se o objeto não tem um construtor definido pelo usuário, um construtor não explicitamente definido no código, o compilador pode gerar um (por exemplo vincular os ponteiros de tabela v).Portanto, seu código terá de chamar 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();
}
  

Consulte também

Referência

Diretivas pragma e __Pragma palavra-chave