Pergunta

Eu estou acostumado a pensar em toda a inicialização de globals / estática-class-membros como acontecendo antes da primeira linha de main (). Mas eu recentemente li em algum lugar que o padrão permite a inicialização a acontecer mais tarde para "ajudar com o carregamento dinâmico de módulos." Eu podia ver isso sendo verdadeiro quando dinâmico vinculação: Eu não esperaria um mundial inicializado em uma biblioteca para ser inicializado antes de eu dlopen'ed biblioteca. No entanto, dentro de um agrupamento de unidades de tradução, bem ligados estaticamente (arquivos .o diretos do meu app) que iria encontrar este comportamento muito intuitiva. Será que isso só acontece de forma tardia quando dinamicamente ligar ou pode acontecer a qualquer momento? (Ou era o que eu li apenas errado;?)

Foi útil?

Solução

O padrão tem o seguinte em 3.6.2 / 3:

É definido implementação-se ou não a inicialização dinâmico (8.5, 9.4, 12.1, 12.6.1) de um objecto de escopo namespace é feito antes da primeira declaração da principal. Se a inicialização é adiada até certo ponto no tempo após a primeira demonstração do principal, que deve ocorrer antes do primeiro uso de qualquer função ou objeto definido na mesma unidade de tradução como o objecto a ser inicializado.

Mas o É claro que você pode Nunca oficialmente dizer quando a inicialização ocorre desde a inicialização ocorrerá antes de acessar a variável! como seguinte:

// t1.cc
#include <iostream>
int i1 = 0;

int main () {
  std::cout << i1 << std::endl

// t2.cc
extern int i1;
int i2 = ++i1;

Eu posso conformar que g ++ 4.2.4 pelo menos aparece para executar a inicialização do 'i2' antes principal.

Outras dicas

O problema que se queria resolver com essa regra é a de carregamento dinâmico. O subsídio não é restrito a carga dinâmica e formalmente poderia acontecer para outros casos. Eu não sei uma implementação que usá-lo para qualquer outra coisa do que o carregamento dinâmico.

Vamos rever um pseudocódigo:

Em DLL:

static int ItsDllVar = 1;
int EXPORTED_FUNCTION() { return ItsDllVar; }

Em aplicação:

static int AppVar1 = 2;
static int AppVar2 = EXPORTED_FUNCTION() + AppVar1;

Assim, de acordo com estático inicializar AppVar2 recebe 1 + 2 = 3

Inicialização lenta aplicável para variáveis ??estáticas locais (independentemente da DLL)

int f()
{
    static int local_i = 5;//it get's 5 only after visiting f()
    return local_i;
}

Eu acho que isso é o que aconteceu no meu caso com g ++ 4.7 e CMake (não tenho certeza se este é um detalhe relevante sobre CMake). Eu tenho um código que registra uma função na fábrica. Baseia-se no construtor chamando de uma variável inicializada globalmente.

Quando este código estava na biblioteca estaticamente ligado a inicialização não aconteceu! Agora é trabalhar bem, quando me mudei para os arquivos objeto que ligavam directamente (ou seja, eles não são combinados em uma biblioteca em primeiro lugar).

Então, eu suspeito que você está correto.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top