Question

Il y a quelques bonnes questions et réponses ici autour du "fiasco d'ordre d'initialisation statique", mais je semble avoir frappé contre une autre expression de celui-ci, Surtout laid car il ne s'écrase pas mais perd et fuit les données.

J'ai une bibliothèque C ++ personnalisée et une application qui relie elle. Il y a un conteneur STL statique dans la bibliothèque qui enregistre toutes les instances d'une classe. Ces instances sont des variables statiques dans l'application.

À la suite du "fiasco" (je crois), nous obtenons le conteneur rempli des instances d'application lors de l'initialisation de l'application, puis la bibliothèque arrive à initialiser et le conteneur est réinitialisé (probablement la mémoire de la mémoire), se terminant uniquement avec les instances de la bibliothèque.

C'est ainsi que je l'ai reproduit avec un code simplifié:

mylib.hpp:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

class MyLibClass {
    static vector<string> registry;
    string myname;
  public:
    MyLibClass(string name);
};

mylib.cpp:

#include "mylib.hpp"

vector<string> MyLibClass::registry;

MyLibClass::MyLibClass(string name)
: myname(name)
{
    registry.push_back(name);
    for(unsigned i=0; i<registry.size(); i++)
        cout << " ["<< i <<"]=" << registry[i];
    cout << endl;
}

MyLibClass l1("mylib1");
MyLibClass l2("mylib2");
MyLibClass l3("mylib3");

myApp.cpp:

#include "mylib.hpp"

MyLibClass a1("app1");
MyLibClass a2("app2");
MyLibClass a3("app3");

int main() {
    cout << "main():" << endl;
    MyLibClass m("main");
}

Compilez les objets avec:

g++ -Wall -c myapp.cpp mylib.cpp
g++ myapp.o mylib.o -o myapp1
g++ mylib.o myapp.o -o myapp2

Exécutez MyApp1:

$ ./myapp1
 [0]=mylib1
 [0]=mylib1 [1]=mylib2
 [0]=mylib1 [1]=mylib2 [2]=mylib3
 [0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1
 [0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1 [4]=app2
 [0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1 [4]=app2 [5]=app3
main():
 [0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=app1 [4]=app2 [5]=app3 [6]=main

Exécutez MyApp2:

$ ./myapp2
 [0]=app1
 [0]=app1 [1]=app2
 [0]=app1 [1]=app2 [2]=app3
 [0]=mylib1
 [0]=mylib1 [1]=mylib2
 [0]=mylib1 [1]=mylib2 [2]=mylib3
main():
 [0]=mylib1 [1]=mylib2 [2]=mylib3 [3]=main

Voici la question, Le vecteur statique a été réinitialisé ou utilisé avant initialisation? Est-ce un comportement attendu?

Si je suis la bibliothèque comme 'mylib.a' (ar rcs mylib.a mylib.o), le problème ne se produit pas, mais probablement parce qu'il n'y a qu'un seul ordre valide pour lier le .a et c'est en ayant La bibliothèque à la dernière place, comme pour MyApp1 ici.

Mais dans notre véritable application, une plus complexe avec de nombreux fichiers d'objets et quelques bibliothèques statiques (.a) partageant quelques registres statiques, le problème se produit et la seule façon dont nous avons réussi à le résoudre jusqu'à présent est de postuler «[10.15] Comment empêcher le« fiasco d'ordre d'initialisation statique »?.

(Je fais toujours des recherches dans notre système de construction quelque peu complexe pour voir si nous lions correctement).

Pas de solution correcte

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top