68 votes

Ordre d'initialisation des variables statiques

Le C++ garantit que les variables d'une unité de compilation (fichier .cpp) sont initialisées dans l'ordre de leur déclaration. Pour un nombre d'unités de compilation, cette règle fonctionne pour chacune d'entre elles séparément (je parle des variables statiques en dehors des classes).

Mais, l'ordre d'initialisation des variables, n'est pas défini entre les différentes unités de compilation.

Où puis-je trouver des explications sur cet ordre pour gcc et MSVC (je sais que se fier à cela est une très mauvaise idée - c'est juste pour comprendre les problèmes que nous pouvons avoir avec le code hérité lors du passage à une nouvelle version majeure de GCC et à un système d'exploitation différent) ?

1voto

Shane MacLaughlin Points 12765

En plus des commentaires de Martin, venant d'un environnement C, je pense toujours aux variables statiques comme faisant partie de l'exécutable du programme, incorporées et allouées dans le segment de données. On peut donc considérer que les variables statiques sont initialisées au moment du chargement du programme, avant l'exécution de tout code. L'ordre exact dans lequel cela se produit peut être vérifié en regardant le segment de données du fichier map produit par l'éditeur de liens, mais pour la plupart des cas, l'initialisation est simultanée.

Edit : dépendre de l'ordre de construction des objets statiques est susceptible d'être non-portable et devrait probablement être évité.

1 votes

Le problème se pose lorsque vous avez des classes C++ dont les constructeurs ont des effets secondaires (par exemple, ils se réfèrent les uns aux autres).

0 votes

Personnellement, j'essaie d'éviter cela autant que possible, car mon expérience en la matière (ou peut-être mon manque de connaissances) n'a pas été bonne. En général, je déplace le gros de la construction vers une fonction Init, appelée au démarrage, ou je passe d'un pointeur statique à un pointeur global initialisé sur le tas au démarrage.

1 votes

@smacl : Bien sûr, mais vous devez alors gérer la fonction Finalize pour désallouer les données, et gérer le fait que parfois Init et Finalize sont appelés plusieurs fois, et parfois, simultanément. L'idiome RAII, ici, combiné à l'initialisation automatique des globaux dans une DLL est tout à fait bienvenu.

0voto

Darien Pardinas Points 146

Si vous voulez vraiment connaître l'ordre final, je vous recommande de créer une classe dont le constructeur enregistre l'horodatage actuel et de créer plusieurs instances statiques de la classe dans chacun de vos fichiers cpp afin que vous puissiez connaître l'ordre final d'initialisation. Assurez-vous de mettre une petite opération coûteuse en temps dans le constructeur afin de ne pas obtenir le même horodatage pour chaque fichier.

0 votes

Faire cela n'apprendrait rien d'utile, puisque l'ordre est formellement indéfini, donc apprendre comment il s'ordonne incidemment sur un linker un jour - dans le but de s'appuyer sur la non-connaissance qui en résulte - est une recette pour un code fragile qui s'effondre le lendemain. Je suppose que cela peut être intéressant pour quelqu'un qui étudie paresseusement comment un linker donné fait les choses, mais combien d'entre nous le font ?

0 votes

En outre, avec l'invention des relinkers dynamiques (il y a longtemps), il n'y a pas vraiment de garantie que l'ordre de construction statique sera le même d'un cycle à l'autre.

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