Ordre global d'initialisation en C : ignorer les dépendances
En C , l'ordre d'initialisation des variables globales au sein d'une unité de traduction est bien défini. Cependant, les dépendances entre les variables globales peuvent être ignorées, ce qui entraîne un comportement surprenant.
Considérez le code suivant :
<code class="cpp">struct Foo; extern Foo globalFoo; struct Foo { Foo() { printf("Foo::Foo()\n"); } void add() { printf("Foo::add()\n"); } static int addToGlobal() { printf("Foo::addToGlobal() START\n"); globalFoo.add(); printf("Foo::addToGlobal() END\n"); return 0; } }; Foo globalFoo; int dummy = Foo::addToGlobal(); int main() { printf("main()\n"); return 0; }</code>
Lorsqu'il est compilé avec GCC 4.4.3, le résultat attendu est :
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
Cela est dû au fait que la variable globale globalFoo est initialisée avant d'appeler la méthode statique Foo::addToGlobal(). Cependant, si nous échangeons l'ordre de globalFoo et de la déclaration factice, le résultat devient :
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
Il semble que les méthodes d'instance de Foo soient appelées sur une instance non construite. En effet, l'ordre d'initialisation globale ignore les dépendances.
Pour garantir que le constructeur de Foo est appelé avant d'initialiser dummy, nous devons nous assurer que globalFoo est défini avant dummy dans la même unité de traduction. Alternativement, nous pouvons utiliser un pointeur statique vers l'instance globale, qui sera initialisée à null avant toute initialisation dynamique. La méthode addToGlobal peut alors vérifier si le pointeur est nul et créer le Foo global si nécessaire.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!