Maison > développement back-end > C++ > Pourquoi l'échange de déclarations de variables globales en C entraîne-t-il un comportement inattendu ?

Pourquoi l'échange de déclarations de variables globales en C entraîne-t-il un comportement inattendu ?

Susan Sarandon
Libérer: 2024-10-30 06:38:03
original
864 Les gens l'ont consulté

 Why Does Swapping Global Variable Declarations in C   Lead to Unexpected Behavior?

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>
Copier après la connexion

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()
Copier après la connexion

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()
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal