A vida útil das static
variáveis de função começa na primeira vez que [0] o fluxo do programa encontra a declaração e termina na finalização do programa. Isso significa que o tempo de execução deve executar alguma manutenção contábil para destruí-lo somente se ele foi realmente construído.
Além disso, como o padrão diz que os destruidores de objetos estáticos devem ser executados na ordem inversa da conclusão de sua construção [1] , e a ordem de construção pode depender da execução específica do programa, a ordem de construção deve ser levada em consideração .
Exemplo
struct emitter {
string str;
emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
~emitter() { cout << "Destroyed " << str << endl; }
};
void foo(bool skip_first)
{
if (!skip_first)
static emitter a("in if");
static emitter b("in foo");
}
int main(int argc, char*[])
{
foo(argc != 2);
if (argc == 3)
foo(false);
}
Resultado:
C:> sample.exe
criado em foo
Destruído em foo
C:> sample.exe 1
Criado em se
Criado em foo
Destruído em foo
Destruído em se
C:> sample.exe 1 2
Criado em foo
Criado em se
Destruído em se
Destruído em foo
[0]
Como o C ++ 98 [2] não tem referência a vários threads, como isso se comportará em um ambiente com vários threads não é especificado e pode ser problemático, como Roddy menciona.
[1]
Seção C ++ 98 3.6.3.1
[basic.start.term]
[2]
No C ++ 11, as estáticas são inicializadas de maneira segura para threads, isso também é conhecido como Magic Statics .
[basic.start.term]
Motti está certo sobre o pedido, mas há outras coisas a considerar:
Os compiladores geralmente usam uma variável de sinalizador oculta para indicar se as estatísticas locais já foram inicializadas e esse sinalizador é verificado em todas as entradas da função. Obviamente, esse é um pequeno impacto no desempenho, mas o que é mais preocupante é que esse sinalizador não é garantido como seguro para threads.
Se você tem uma estática local, como acima, e
foo
é chamado de vários encadeamentos, pode haver condições de corrida queplonk
podem ser inicializadas incorretamente ou mesmo várias vezes. Além disso, nesse caso,plonk
pode ser destruído por um thread diferente daquele que o construiu.Apesar do que diz o padrão, eu ficaria muito cauteloso com a ordem real da destruição estática local, porque é possível que você involuntariamente confie em uma estática ainda válida após ser destruída, e isso é realmente difícil de rastrear.
fonte
As explicações existentes não são realmente completas sem a regra real da Norma, encontrada em 6.7:
fonte
FWIW, o Codegear C ++ Builder não destrói na ordem esperada, de acordo com o padrão.
... que é outra razão para não confiar na ordem de destruição!
fonte
As variáveis estáticas são ativadas quando a execução do programa é iniciada e permanecem disponíveis até o término da execução do programa.
As variáveis estáticas são criadas no segmento de dados da memória .
fonte