420 votes

Quelle est la durée de vie d’une variable statique dans une fonction C++ ?

Si une variable est déclarée comme `` dans la portée d’une fonction c’est initialisée uniquement une fois et conserve sa valeur entre les appels de fonction, nous le savons tous, mais quelle est exactement sa durée de vie ? Quand appelés son constructeur et un destructeur ?


P.S. pour ceux qui veulent connaître pourquoi j’ai posé la question si je connaissais déjà la réponse ?

301voto

Motti Points 32921

La durée de vie de la fonction static variables débute la première fois[0] le flux de programme des rencontres de la déclaration, et il se termine à la fin du programme. Cela signifie que l'exécution doit effectuer un certain livre en gardant à l'ordre de détruire que si elle a été effectivement construit.

En outre, étant donné que la norme dit que les destructeurs " des objets globaux doivent être exécutées dans l'ordre inverse de l'achèvement des travaux de construction[1] et de l'ordre de la construction peut dépendre de la spécificité de l'exécution du programme, de l'ordre de la construction doit être pris en compte.

Exemple

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

Sortie:

C:>sample.exe
Créé en foo
Détruit dans foo

C:>sample.exe 1
Créée en si
Créé en foo
Détruit dans foo
Détruit en si

C:>sample.exe 1 2
Créé en foo
Créée en si
Détruit en si
Détruit dans foo

[0] Depuis C++98 n'a pas de référence à plusieurs threads de savoir comment cela va être de se comporter dans un environnement multi-thread est indéfini, et peut être problématique comme Roddy mentionne.

[1] C++98 section 3.6.3.1 [de base.commencer.terme]

134voto

Roddy Points 32503

Il est juste à propos de l'ordre, mais il ya quelques autres choses à considérer:

Les compilateurs utilisent généralement caché variable d'indicateur pour indiquer si le local de la statique ont déjà été initialisé, et ce drapeau est vérifiée à chaque entrée de la fonction. Évidemment, c'est un petit gain de performance, mais ce qui est plus inquiétant, c'est que ce drapeau n'est pas garanti d'être thread-safe.

Si vous avez un local statique, comme ci-dessus, et " foo "est appelé à partir de plusieurs threads, vous pouvez avoir des conditions de course cause "pinard" pour être initialisé de manière incorrecte ou même plusieurs fois. Aussi, dans ce cas, 'pinard pourraient être détruits par un autre thread que celui qui l'a réalisée.

En dépit de ce que dit la norme, je serais très méfiant de la commande locale statique de la destruction, car il est possible que vous pourriez involontairement compter sur un statique étant toujours valide après avoir été détruite, et c'est vraiment difficile à retracer.

8voto

Roddy Points 32503

FWIW, Codegear C++ Builder n’est pas être détruit dans l’ordre attendu conformément à la norme.

... qui est une autre raison pour ne pas se fier sur la destruction de la commande !

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X