Forum Programmation.c++ ld me détruit des symboles importants

Posté par  .
Étiquettes : aucune
0
17
nov.
2004
Hello,

Je ne sais pas si c'est le bon forum pour demander ça, mais je ne sais pas ou poster...

J'ai mon programme décomposé en librairies statique. Dans ces librairies je déclare des instances de classes qui ne fonctionne que par effets de bords.

Au moment de l'édition des liens, mon objets passe à la poubelle.
Je comprend bien qu'une classe ou des fonctions non utilisés soient supprimés à l'édition des liens, mais là il me supprime un objet qui aurait du provoquer une allocation mémoire et l'appel au constructeur !

J'ai essayer plein de truc, mais les seules solutions pour que mes objets soient effectivement présent est d'avoir un liens direct entre le main et mon objet, ou alors de déclarer mon objet directement dans le main.


Si vous connaissez un meilleur forum pour ce type de question, dites-le moi.


Merci
  • # Bonne question

    Posté par  (site web personnel) . Évalué à 1.

    Quand tu parles d'effet de bord pour tes objets, de quoi parles-tu ? de plugins statiques (terme mal choisi) ? des objets qui ne sont utilisés que rarement (voire jamais) ? Est-ce que tes objets ne sont là que pour charger des dynlibs (dll/so) ?

    Un solution consiste peut etre à une virtualisation des classes de tes objets et (via la surcharge des constructeurs) enregistrer les objets dans un vecteur/tableau.

    Un jour libre ?

    • [^] # Re: Bonne question

      Posté par  . Évalué à 1.

      Je vais prendre un exemple pris de mon code actuel (ici, ce n'est pas vraiment un effet de bord du constructeur, mais simplement une utilisation non-explicile d'un objet) :
      J'ai un enssemble de classes dérivant toutes d'une même classe de base, avec une seule instance de chaque classe. Chacune de ces classes représente un module de mon application.
      //en-tête API de ma librairie
      class base {
        base() : next(first) { first = this; }
       
        static base* first;
        base* next;
      }
      
      //Code c++ de la librairie
      base* base::first = NULL;
      classe derivee : public base { }
      derivee unUniqueObjet;
      
      //code du main
      base * current = base::first;
      while (current) {
        printf("coucou\n");
        current = current->next;
      }
      
      Dans ce cas, le main devrait afficher "coucou", mais ce n'est pas le cas car le linker considère que l'objet "unUniqueObjet" n'est pas utilisé par main, et il me le vire à l'edition des liens.
      Si je déclare "unUniqueObjet" dans le main, ça fonctionne. Mais j'aimerais autant ne pas le faire : ça m'évite d'avoir plein de choses inutiles dans les en-têtes.
      • [^] # Re: Bonne question

        Posté par  . Évalué à 1.

        Dans ce cas, le main devrait afficher "coucou", mais ce n'est pas le cas car le linker considère que l'objet "unUniqueObjet" n'est pas utilisé par main, et il me le vire à l'edition des liens.


        Si je comprends bien, tu veux utiliser unUniqueObjet dans ton main.

        Ca me semble étrange que ce soit le linker qui râle : lors de la compilation de ton main, il n'y a aucune déclaration de unUniqueObject, et ça ne devrait donc pas compiler. Tout ce que tu utilises dans une unité de traduction (c.a.d ce que te donne le préprocesseur) doit y être déclaré.

        Dans ton cas, il faut donc que tu déclares unUniqueObjet dans le fichier contenant la déclaration de tes classes de la bibliothèque.

        P.S. avec du code qui compile réellement, ton exemple serait plus sympa à lire :-)
        • [^] # Re: Bonne question

          Posté par  (site web personnel) . Évalué à 3.

          Non l'idée est d'avoir une chaine d'objets comportant les adresses d'objets d'une classe ou d'une classe dérivée, la virtualité de la construction insérant directement l'adresse de l'objet dans la chaine (uenregistrement typique de plugins).

          Quand lance le programmes, les objets non déclarés dans le 'main' ne sont pas ajoutés à la chaine comme ils devraient.

          Un jour libre ?

          • [^] # http://www.chezmoicamarche.com

            Posté par  . Évalué à 2.

            Je viens de refaire le test chez moi et cela fonctionne dans tous les cas.

            g++ v3.3.3 sur une Fedora Core 2.

            Fais un "g++ -v" pour connaître ta version du compilo.

            Ah également: Essaie d'éditer tes liens avec g++ plutôt qu'avec ld directement, j'ai déjà eu ce genre de problème.

            g++ -O2 -c lib.cpp -o lib.o

            puis

            g++ -O2 -o effet main.cpp lib.o

            pour éditer le fichier final 'Effet".

            Bonne chance.
            • [^] # Re: http://www.chezmoicamarche.com

              Posté par  . Évalué à 1.

              Oui, dans ce cas ça fonctionne. C'est quand je passee par une librairie que ça ne marche pas :

              g++ -O2 -c lib.cpp lib.o
              ar cru lib.a lib.o
              ranlib lib.a

              g++ -O2 -o effet main.cpp lib.a
      • [^] # Re: Bonne question

        Posté par  (site web personnel) . Évalué à 2.

        Ben ouai, c un problème effectivement.
        Est-ce que tu as essayer de déclarer tes objets comme volatiles ? ca forcera peut-etre la présence de l'objet.

        Avec quel version de gcc compiles-tu ? As tu le même problème en mode debug ?

        Un jour libre ?

      • [^] # Re: Bonne question

        Posté par  . Évalué à 1.

        effectivment il s'agit d'une optimisation du compilateur qui jette tous les initialiseurs statiques non référencés...regarde dans les options du compilo(y a aussi des modifieurs inline pour ne pas mettre d'option à la compilation mais directement dans le code si je me souviens bien) pour le forcer à ne pas jetter les données statiques non référencés...

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.