Forum Programmation.c++ Faire une réduction de code en supprimant les fonctions non utilisées

Posté par  .
Étiquettes : aucune
0
7
sept.
2011

Bonjour,
supposons un code contenant plusieurs classes, pleins de méthodes, mais l'utilisateur n'utilise que 2 classes et sur ces 2 classes uniquement 3 méthodes sur les 10 proposées. Y a t-il un logiciel qui peut, avant la compilation :
* supprimer les classes non utilisées
* supprimer les méthodes non utilisées

Puis une fois cela fait il compile les nouveaux fichiers (bien sûr le code source de départ ne change pas). Le but est d'avoir un programme qui ne contient dans son code que le nécessaire. Merci
Bonne fin de journée

  • # Pour le C

    Posté par  . Évalué à 2.

    Marrant ma recherche google (g++ remove unused function) me revoie ça

    http://stackoverflow.com/questions/6687630/c-c-gcc-ld-remove-unused-symbols

    même si généralement un -Os suffit :)

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

    • [^] # Re: Pour le C

      Posté par  . Évalué à 1.

      ?!
      Ça n'a jamais supprimé des parties du code.
      Il parle de ne pas compiler les fonctions, méthodes et autres non utilisées.

  • # Marche pas, ou je m'y prends mal

    Posté par  . Évalué à 0.

    Voici un code : main.cpp

    #include <iostream>
    
    using namespace std;
    
    class A
    {
    public:
        A(int a);
        void f1();
        void f2();
    private:
        int m_ok;
    
    };
    
    A::A(int a)
    {
        m_ok=a;
    }
    
    void A::f1()
    {
        std::cout<<"f1";
    }
    
    void A::f2()
    {
        std::cout<<"f2";
    }
    
    int main()
    {
        A a(5);
        a.f1();
        cout << "Hello world!" << endl;
        return 0;
    }
    
    

    Normalement la taille du fichier final devrait être la même que lorsque que f2 n'existe pas. Comment faire ? Merci de préciser la ligne de code. Moi j'obtiens la même taille avec ou sans f2 avec le -Os (j'ai essayé le reste, soit cela ne change rien, soit j'ai des erreurs). D'avance merci
  • # Ok à priori cela fonctionne

    Posté par  . Évalué à 1.

    g++ -Os -fdata-sections -ffunction-sections main.cpp -o main -Wl,--gc-sections -Wl,--strip-all

  • # J'ai séparé ma classe en 2 fichiers .h et .cpp et le code est plus gros

    Posté par  . Évalué à 0.

    Quelqu'un peut essayer pour voir ? j'ai l'impression que cela ne fonctionne que sur un fichier. C'est à dire qu'il optimise le fichier tout seul. Merci

    • [^] # Re: J'ai séparé ma classe en 2 fichiers .h et .cpp et le code est plus gros

      Posté par  . Évalué à 1.

      bon tu auras moins de soucis si la chaine de caractère renvoyé par f2 ne contient pas f2; ces chaines statiques sont stocké ailleurs et ne sont pas détecté comme étant inutilisé (ou, en tout cas, pas avec les options en question )

      > g++ -Os -fdata-sections -ffunction-sections test.cc test2.cc -Wl,--gc-sections -Wl,--strip-all -o plop  
      >grep pouet  plop
      Fichier binaire plop concorde
      >grep f2  plop
      >
      
      

      en gros j'ai fait un .h pour la class et le .cc à coté et remplacé la chaine "f2" par "pouet" (le nom de la fonction est inchangé)

      Il ne faut pas décorner les boeufs avant d'avoir semé le vent

      • [^] # Re: J'ai séparé ma classe en 2 fichiers .h et .cpp et le code est plus gros

        Posté par  . Évalué à 0.

        J'ai remplacé les chaînes par des nombres et c'est pareil. J'ai une taille plus petite si f2() n'est pas présente dans les fichiers. Donc cela veut dire que :
        * soit cela ne fonctionne pas
        * soit je n'arrive pas à faire cela sur plusieurs fichiers

        Une idée ?

        • [^] # Re:J'ai séparé ma classe en 2 fichiers .h et .cpp et le code est plus gros

          Posté par  . Évalué à 3.

          Bon je comprend pas vraiment le coups des nombres ni le soucis avec le C++ mais voici les règles que j'utilise pour du code en C (donc ça devrais etre transposable).
          Si j'ai deux fichiers (ou plusieurs ) contenant du code potentiellement non-utilisé mais sans que je souhaite le supprimer manuellement je fais

          gcc -c -Os -fdata-sections -ffunction-sections main.c -o main.o
          gcc -c -Os -fdata-sections -ffunction-sections file1.c -o file1.o

          Ca demande à GCC pour chaque fichier de créer une section header elf spécifique à chacun de ces fichiers.
          Un fichier contient a minima une section .bss pour les données et une section .text pour le programme. Quand tu ne spécifie rien, un fichier = une section de chaque type.

          Donc l'élimination du code inutilisé ce base sur l'entité d'un fichier, si une partie est utilisé le fichier est entièrement mis dans l'exe finale.

          Si à l’intérieur d'un fichier je souhaite plusieurs sections pour permettre une élimination plus fine (par exemple une par fonction ) je dois spécifier ca dans l'attribut de la fonction

          void foobar (void) attribute ((section ("bar")));

          ensuite l’édition de lien (soit avec ld soit avec gcc en front-end) ce fait avec l'option
          --gc-sections (pour garbage collector section ) c'est a dire mettre à la poubelle les sections non-utilisée.

          ensuite j'utilise soit readelf (des binutils), soit objdump -Dslhx pour voir ce que contient le code finalement linké

          Il faut bien ce rendre compte qu'en faisant ça, on multiplie le nombre de section et donc on augmente la taille de l'exe finale il faut donc faire des compromis.

          Je fais ca régulièrement car j'utilise gcc pour produire du code embarqué ou chaque kilo de mémoire est compté et je dois maitrisé le placement de certaine fonction en flash et d'autre en RAM.
          Voila mes deux cts

          • [^] # Re:J'ai séparé ma classe en 2 fichiers .h et .cpp et le code est plus gros

            Posté par  . Évalué à 1.

            Cool comme astuce :-) As-tu eu l'occasion de tester le LTO ?

            • [^] # Re:J'ai séparé ma classe en 2 fichiers .h et .cpp et le code est plus gros

              Posté par  . Évalué à 1.

              Le link-time-optimisation ?
              Non, pas essayé tout simplement parce qu'en embarqué c'est vraiment du bas niveau dont j'ai besoin et pas de l'objet elf. Je ré-écris le crt0.s (normal il faut bien initialiser le bus externe du micro et lui dire qu'il y a du monde dehors ;-) ), je vire le crt1 (mais en c++ tu en aura besoin c'est lui qui invoque les constructeurs de tes class globales) et j'écris mes script ld correspondant à la mémory map de la carte. Pas de stdlibs, je crée en assembleur les trucs vraiment indispensable (comme memcpy,save_interrupt et restore_interrupt) pour que le link fonctionne.
              En gros le dernier programme que j'ai fais l'objet elf fais 90Ko mais en hex à flasher il fait moins de 30Ko (et il fait plein de choses)
              Les programmes que j'écris sont stand alone, pas d'os ni fs ni beaucoup de flash ni beaucoup de ram, c'est byzance quand une des deux mémoire fais plus de 128ko.

  • # Template programming

    Posté par  . Évalué à 2.

    Les classes ou fonctions templates non utilisées ne sont pas compilés. Ça ne résout pas le problème, mais ça peut constituer une partie de la solution.

    • [^] # Re: Template programming

      Posté par  . Évalué à 1.

      Que veux tu dire par là ? moi j'ai l'impression que lorsque les classes sont séparées en fichiers dans un projet cela ne fonctionne pas. Car déjà la taille ne change pas si j'utilise f2 ou non dans le main. Et de plus j'ai une taille plus grande que si tout est dans le même fichier.
      Des pistes ? c'est la raison pour laquelle je voulais savoir s'il n'y avait pas un utilitaire pour faire cela car je n'arrive pas à faire cela avec le compilateur (ni avec strip d'ailleurs).
      Merci

    • [^] # Re: Template programming

      Posté par  . Évalué à 1.

      Oui et Non la solution ce serait d'avoir un système qui supprime les fonctions non utilisées...pour avoir le minimum vital.

      • [^] # Re: Template programming

        Posté par  . Évalué à 1.

        Ton problème peut se voir de 2 façons (je n'ai pas très bien compris celle que tu cherches à réaliser) :
        A) détecter le code mort et le supprimer des sources
        B) avoir le binaire le plus petit possible.

        Pour B, essaye d'utiliser les options de gcc adéquates, puis un coup de strip(1) devrait faire l'affaire. Sauf si tu charge ton code dynamiquement (dlopen,...).

        Pour A, tu pourrais peut-être comparer la liste des symboles entre le binaire complet et allègé.

        • [^] # Re: Template programming

          Posté par  . Évalué à 1.

          Je cherche juste à faire en sorte que le code "mort" n'existe plus et que la taille finale soit celle que l'on aurait si celui-ci n'existait pas. Dans l'exemple que j'ai donné je cherche en aillant des fichiers par classe (ce que l'on a de façon traditionnelle) à faire en sorte que la taille finale soit la même quand f2 n'existe pas et quand f2 existe.
          Cependant je n'y arrive pas, il reste une différence entre mon executable compilé avec f2 et sans f2.
          Pourquoi je demande cela ? un exemple Qt sur un système embarqué (Android par exemple) mais je n'utilise que 10% des classes, c'est dommage de griller toute cette place et d'avoir une application énorme (bien sûr il faut utiliser la version de Qt avec la bonne licence, quitte à payer pour l'entreprise). Voilà
          Merci

          • [^] # Re: Template programming

            Posté par  . Évalué à 1.

            Bon ok j'ai compris maintenant ;-) C'est normal, gcc n'a aucun moyen de savoir que tu ne vas pas utiliser tous les symboles d'un objet que tu lies, ou que cet objet n'utilise pas lui-même tous ses propres symboles. Car cette information est uniquement connue au moment de la compilation d'une unité. Exemple: A.c defini FA() mais ne l'utilise pas, lorsque gcc le compile, il n'enlève pas FA() car il pourrait-être utilisé dans une autre unité; lorsque tu linke ton B.o (qui n'utilise toujours pas FA()) à A.o, gcc ne sait plus que FA() n'est pas utilisé par A.c et ne peut donc l'enlever. Regarde du côté de http://gcc.gnu.org/wiki/LinkTimeOptimization qui doit répondre à ce problème. Je n'en sais pas plus, désolé. Peut-être vas-tu devoir recompiler binutils et gcc pour cela.

            PS: Si tu ne les connaissais pas, les outils nm, objdump et strip devraient pouvoir t'aider à voir ce qu'il se passe.

            • [^] # Re: Template programming

              Posté par  . Évalué à 0.

              gcc ne sait plus que FA() n'est pas utilisé par A.c
              s/gcc/le linker/

          • [^] # Re: Template programming

            Posté par  . Évalué à 2.

            Je cherche juste à faire en sorte que le code "mort" n'existe plus et que la taille finale soit celle que l'on aurait si celui-ci n'existait pas.

            C'est déjà le cas avec les templates, tu n'utilises pas, ça n'est pas compilé, ça n'existe pas dans le binaire.

            • [^] # Re: Template programming

              Posté par  . Évalué à 1.

              Oui merci sauf que ce n'est pas forcément pour ma bibliothèque que je veux faire cela (Qt en l'occurrence). Merci

  • # Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

    Posté par  . Évalué à -2.

    Ils devraient peut être donner une explication sur la pertinence ou non du commentaire. Une exemple flagrant : je donne un code d'exemple pour que les personnes puissent tester comme moi si cela fonctionne ou pas. Au final on constate quoi ? gcc ne sait pas le faire. Donc je dirais que ma question était pertinente, pas pour tous certes, à croire que y en a qui n'ont rien de mieux à faire.
    Et ce n'est pas un troll de vendredi :-)

    • [^] # Re: Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

      Posté par  . Évalué à -3.

      Soit tu fermes ta gueule, soit tu causes toujours.

      Les gens votent pertinent ou inutile en leur âme et conscience selon ce qu'ils souhaitent, ou pas, lire sur ce site.

      Donc non ils ne devraient pas donner une explication, sauf s'ils le souhaitent.

      Je te moinsse. Voilà :)

      • [^] # Re: Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

        Posté par  . Évalué à -5.

        Non mais tu te crois ou là ? Va te ferme enculer pauvre connard, moi aussi je peux utiliser ton propre vocabulaire !!!

        • [^] # Re: Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

          Posté par  . Évalué à 0.

          Désolé mais c'est toi qui part en "coup de gueule", à la limite du caca nerveux, parce qu'on t'a moinssé un commentaire. De plus tu te permets d'être méprisable envers les contributeurs de ce site :

          à croire que y en a qui n'ont rien de mieux à faire.

          Tu noteras également que bien que n'ayant pas été très poli avec mon "ferme ta gueule", je ne t'ai pas insulté, comme tu le fais à mon encontre en utilisant le mot "connard".

          • [^] # Re: Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

            Posté par  . Évalué à 1.

            Bonjour,
            Je ne pars pas en coup de gueule comme vous le faîtes remarquer, j'ai juste indiqué que je préférais des éléments constructifs. Je vais juste décrire une dernière fois la chose que j'ai trouvé étrange : je donne un code pour faciliter les tests et on "moinse" ce code ? pourquoi ? aucune idée, je voulais juste permettre de faciliter les choses. Au final ma question n'était pas si "idiote" que cela puisque l'on m'a apporté le fait que gcc ne pouvait réduire la mémoire sur des fichiers séparés(gcc ou autre je voulais savoir si un utilitaire existait).

            Ce n'est pas un mépris envers les utilisateurs du site, juste une remarque sur le fait que la mode "facebook" j'aime/j'aime pas n'est peut être pas adaptée. Une remarque du style : "ton code n'apporte rien" et voilà c'est tout. Cela fait plusieurs années que je suis sur ce site, pas juste quelques mois et j'ai toujours répondu (sauf aujourd'hui je vais y venir) avec politesse.

            Pour mon insulte, elle montrait juste le comportement que vous aviez. J'espère naturellement que vous n'en êtes pas un, et que au final vous adaptez (comme je l'admets) que c'était déplacé et que des insultes n'apportent rien (car un "ferme ta gueule" est au niveau d'un "connard" je trouve. Après cela se discute...). Juste ne rien écrire quand les commentaires sont non appropriés aurait peut être suffit.

            Personnellement j'aimerais en rester là. Je programme depuis presque 30ans et je viens ici lorsque j'ai quelques questions pour mon travail en général. J'aime comme beaucoup de personnes ce côté "agréable" des commentaires. Je ne connais pas tout, j'aime apprendre et mes commentaires essayent d'expliquer au mieux ma pensée. Voilà !!
            Sur ce, passez une bonne fin de journée
            Bien Cordialement

            • [^] # Re: Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

              Posté par  . Évalué à 0.

              C'est peut-être un problème si quelques personnes moinssent à tord, trop vite sans réfléchir. En effet des visiteurs qui viendraient après et qui eux pourraient saisir la pertinence du commentaire, ne le voient tout simplement pas à moins de le déplier.

              Je ne pense pas que l'on puisse y faire grand chose.

              Je ferai attention à m'exprimer de manière plus cordiale à l'avenir.

              Bonne soirée à vous.

      • [^] # Re: Petit coup de gueule : Visiblement y en a qui "moinsse" les commentaires

        Posté par  . Évalué à -1.

        Et puis faudra apprendre à écrire le français, y a pas une grosse faute de grammaire qui pique les yeux :-) mais bon vu ton niveau c'est normal.

Suivre le flux des commentaires

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