J’ai hérité code C++ que je suis censé pour supprimer code inutilisé de. Le problème est que la base de code est grande.
J’aimerai trouver des code qui n’est jamais appelé/jamais utilisé ?
J’ai hérité code C++ que je suis censé pour supprimer code inutilisé de. Le problème est que la base de code est grande.
J’aimerai trouver des code qui n’est jamais appelé/jamais utilisé ?
Il existe deux variétés de code inutilisé:
Pour le premier type, un bon compilateur peut aider:
-Wunused
(GCC, Clang) devrait mettre en garde sur les variables, Clang inutilisés de l'analyseur a même été incrémenté pour avertir sur les variables qui ne sont jamais lire (même si utilisé).-Wunreachable-code
(âgés de GCC, supprimée en 2010) devrait mettre en garde sur les blocs qui ne sont jamais accessibles (ce qui arrive avec les premiers retours ou des conditions toujours true)catch
blocs, parce que le compilateur ne peut généralement pas prouver qu'aucune exception n'est levée.Pour le second type, c'est beaucoup plus difficile. Statiquement, il exige de tout programme d'analyse, et même si le lien à l'optimisation du temps peut effectivement supprimer le code mort, dans la pratique, le programme a été tellement transformé au moment où il est effectué, qu'il est presque impossible de transmettre des informations utiles à l'utilisateur.
Il y a donc deux approches:
gcov
. Notez que des indicateurs spécifiques devrait être adopté lors de la compilation pour que cela fonctionne correctement). Vous exécutez l'outil de couverture de code avec un bon ensemble de diverses entrées (votre unité de tests-ou non-des tests de régression), le code mort est nécessairement dans l'évangile de code... et donc vous pouvez commencer à partir d'ici.Si vous êtes très intéressé par le sujet, et ont le temps et l'envie de travailler à un outil par vous-même, je vous recommande d'utiliser le Cliquetis des bibliothèques de construire un tel outil.
Parce que Clang va analyser le code pour vous, et d'effectuer la résolution de surcharge, vous n'aurez pas à traiter avec le C++ langages de règles, et vous serez en mesure de se concentrer sur le problème à portée de main.
Cependant ce genre de technique ne peut pas identifier le virtuel remplace qui ne sont pas utilisés, car ils pourraient être appelés par le code tiers vous ne pouvez pas raisonner sur.
Pour le cas de la fraction inutilisée du fonctionnement de l'ensemble (et non utilisés à des variables globales), GCC peut réellement faire la plupart du travail pour vous à condition que vous êtes en utilisant GCC et GNU ld.
Lors de la compilation de la source, utilisez -ffunction-sections
et -fdata-sections
, puis lors de la liaison utilisation -Wl,--gc-sections,--print-gc-sections
. L'éditeur de liens maintenant la liste de toutes les fonctions qui pourraient être supprimés parce qu'ils n'ont jamais été appelés et toutes les variables globales qui n'ont jamais été référencé.
(Bien sûr, vous pouvez également passer l' --print-gc-sections
de la partie et laisser l'éditeur de liens de supprimer les fonctions en silence, mais de les garder dans la source).
Remarque: ce ne trouverez inutilisés des fonctions complètes, il ne fera rien à propos de la mort de code à l'intérieur des fonctions. Les fonctions appelées à partir du code mort dans des fonctions en direct seront également conservés.
En C++caractéristiques spécifiques aussi causer des problèmes, en particulier:
Dans les deux cas, quoi que ce soit utilisé par une fonction virtuelle ou un mondial de la variable constructeur doit également être maintenu autour de.
Un inconvénient supplémentaire est que si vous êtes la construction d'une bibliothèque partagée, les paramètres par défaut de GCC permettra d'exporter toutes les fonctions de la bibliothèque partagée, à l'origine pour être "utilisé" aussi loin que l'éditeur de liens. Pour corriger cela, vous devez définir la valeur par défaut de cacher des symboles à la place de l'exportation (en utilisant par ex. -fvisibility=hidden
), puis de choisir explicitement les fonctions exportées que vous avez besoin pour l'exportation.
Eh bien, si vous à l'aide de g++, vous pouvez utiliser cet indicateur -Wunused
Selon la documentation:
Avertir à chaque fois qu'une variable est inutilisé à part sa déclaration, chaque fois que une fonction est déclarée statique, mais jamais défini, chaque fois que l'étiquette est déclarées mais non utilisées, et à chaque fois qu'un déclaration calcule un résultat pas explicitement utilisé.
http://docs.freebsd.org/info/gcc/gcc.info.Warning_Options.html
Edit: Voici d'autres utiles drapeau -Wunreachable-code
Selon la documentation:
Cette option est destinée à avertir lorsque le compilateur détecte au moins un ensemble de ligne de code source ne sera jamais exécutée, parce que certaines condition n'est jamais remplie ou parce que c'est au terme d'une procédure ne retourne jamais.
Mise à jour: j'ai trouvé de sujet similaire détection du code Mort en héritage en C/C++ projet
Je pense que vous cherchez un outil de couverture de code . Un outil de couverture de code analysera votre code en cours d'exécution et vous indiquera quelles lignes de code ont été exécutées et combien de fois, ainsi que celles qui ne l'ont pas été.
Vous pourriez tenter de donner une chance à cet outil de couverture de code open source: TestCocoon - outil de couverture de code pour C / C ++ et C #.
La vraie réponse est ici: Vous ne pouvez jamais être vraiment sûr.
Au moins, pour les non négligeable de cas, vous ne pouvez pas être sûr que vous avez obtenu tout cela. Considérons la suite de l'article de Wikipedia sur le code inaccessible:
double x = sqrt(2);
if (x > 5)
{
doStuff();
}
Comme Wikipedia correctement des notes, un savant compilateur peut être capable d'attraper quelque chose comme ça. Mais envisager une modification:
int y;
cin >> y;
double x = sqrt((double)y);
if (x != 0 && x < 1)
{
doStuff();
}
Sera le compilateur attraper? Peut-être. Mais pour ce faire, il devra faire plus que de courir sqrt
contre un scalaire constante de la valeur. Il devra comprendre qu' (double)y
sera toujours un entier (facile), puis de comprendre les mathématiques de la gamme de sqrt
pour l'ensemble des entiers (dur). Un système sophistiqué, le compilateur pourrait être en mesure de le faire pour l' sqrt
de la fonction, ou pour chaque fonction math.h, ou pour toute fixe d'entrée de la fonction dont le domaine peut comprendre. Cela devient très, très complexe, et cette complexité est essentiellement illimitée. Vous pouvez continuer à ajouter des couches de sophistication à votre compilateur, mais il y aura toujours un moyen de se faufiler dans un code qui sera inaccessible pour un ensemble donné d'intrants.
Et puis il y a l'entrée des ensembles qui, tout simplement, de ne jamais entrer. D'entrée qui n'auraient pas de sens dans la vie réelle, ou bloqué par une logique de validation ailleurs. Il n'y a aucun moyen pour le compilateur de savoir à propos de ceux-ci.
Le résultat de ceci est que, bien que les outils logiciels d'autres ont mentionné sont extrêmement utiles, vous n'allez savoir pour sûr que vous avez pris tout à moins que vous passez par le code manuellement par la suite. Même alors, vous ne serez jamais être certain que vous ne manquiez de rien.
La seule vraie solution, à mon humble avis, est d'être aussi vigilants que possible, l'utilisation de l'automatisation à votre disposition, refactoriser où vous le pouvez, et de chercher constamment des moyens d'améliorer votre code. Bien sûr, c'est une bonne idée de le faire de toute façon.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.