Blog 4 min de lecture

Traquer les code smells C++ : l’approche base de données

Share this article
Traquer les code smells C++ : l’approche base de données

L'analyse statique ne consiste pas seulement à trouver directement des bugs, mais aussi à trouver les situations propices aux bugs qui peuvent nuire à la lisibilité et à la maintenabilité du code. L'analyse statique peut examiner de nombreuses autres propriétés du code :

  • Les métriques de code: par exemple, les méthodes avec trop de boucles et d'instructions if, else, switch et case finissent par être difficiles à comprendre, donc difficiles à maintenir. Les compter via la métrique de complexité cyclomatique est un excellent moyen d'évaluer quand une méthode devient trop complexe.
  • Les dépendances: si les classes de votre programme sont enchevêtrées, les effets de tout changement dans le code deviennent imprévisibles. L'analyse statique peut aider à évaluer quand les classes et les composants sont enchevêtrés.
  • L'immutabilité: les types utilisés concurremment par plusieurs threads devraient être immuables ; sinon vous devrez protéger les accès en lecture/écriture à l'état avec des stratégies de verrous complexes qui finiront par être impossibles à maintenir. L'analyse statique peut garantir que certaines classes restent immuables.
  • Le code mort: le code mort est du code qui peut être supprimé en toute sécurité, car il n'est plus invoqué à l'exécution. Non seulement il peut être supprimé, mais il doit l'être, car ce code supplémentaire ajoute une complexité inutile au programme. L'analyse statique peut trouver la majeure partie du code mort de votre programme (mais pas la totalité).
  • Les changements cassants d'API: si vous présentez une API à vos clients, il est très facile de supprimer un membre public sans s'en apercevoir et ainsi de casser le code de vos clients. L'analyse statique peut comparer deux états d'un programme et vous avertir de ce piège.
  • L'utilisation des API: certaines API sont destinées à être utilisées avec précaution. Par exemple, une classe qui détient des champs disposable doit généralement être disposable elle-même, sauf lorsque la durée de vie du champ disposable n'est pas alignée sur celle de l'instance de la classe — ce qui sent alors le problème de conception.

Un code smell peut aussi être considéré comme une situation propice aux bugs. En voici la définition de Wikipédia :

In computer programming, code smell, (or mauvaise odeur) is any symptom in the source code of a program that possibly indicates a deeper problem. According to Martin Fowler, "a code smell is a surface indication that usually corresponds to a deeper problem in the system". Another way to look at smells is with respect to principles and quality: "smells are certain structures in the code that indicate violation of fundamental design principles and negatively impact design quality". Code smells are usually not bugs—they are not technically incorrect and do not currently prevent the program from functioning. Instead, they indicate weaknesses in design that may be slowing down development or increasing the risk of bugs or failures in the future. Bad code smells can be an indicator of factors that contribute to technical debt. Robert C. Martin calls a list of code smells a "value system" for software craftsmanship.

De nombreux outils utiles peuvent détecter des bugs dans une base de code C++, notamment Cppcheck, Clang-Tidy et l'analyseur de Visual Studio. Mais qu'en est-il de la détection des code smells ?

Si les créateurs d'outils d'analyse statique peuvent décider quelles situations sont considérées comme des bugs, les code smells sont plus subjectifs et dépendent des choix de l'équipe de développement. Par exemple, une équipe pourrait considérer qu'une méthode de plus de 20 lignes est complexe, tandis qu'une autre équipe pourrait fixer le maximum à 30. Si un outil détecte les code smells, il doit aussi permettre aux équipes de personnaliser les règles et les seuils concernés.

Le code comme donnée : la meilleure façon de détecter les code smells

L'analyse statique, c'est l'idée d'analyser le code source pour en extraire diverses propriétés et d'en faire rapport, mais c'est aussi, philosophiquement, l'idée de traiter le code comme une donnée. Cela peut sembler inhabituel aux développeurs d'applications, car nous avons l'habitude de voir le code source comme des instructions, des procédures et des algorithmes. Mais traiter le code comme une donnée est aussi extrêmement puissant.

Après avoir analysé un fichier source, nous pouvons extraire son AST et générer un modèle contenant une mine d'informations utiles sur le code. Nous pouvons ensuite interroger ce modèle à l'aide d'un langage de requêtes sur le code similaire à SQL.

CppDepend fournit un langage de requêtes sur le code nommé CQLinq pour interroger la base de code comme une base de données. Les développeurs, concepteurs et architectes peuvent définir leurs propres requêtes pour trouver facilement les code smells.

Avec CQLinq, nous pouvons combiner des données issues des métriques de code, des dépendances, de l'utilisation des API et d'autres informations du modèle pour définir des requêtes avancées qui identifient des code smells spécifiques.

Voici un exemple de requête CQLinq qui trouve les méthodes les plus complexes :

bugs

Résumé

Il est souvent préférable de combiner plusieurs outils C++ pour détecter les problèmes de votre base de code : certains outils se concentrent sur les bugs, tandis que d'autres peuvent aussi détecter les code smells. CppDepend réunit ces approches en offrant un moyen simple de définir des requêtes personnalisées et en important les résultats d'autres outils d'analyse statique pour qu'ils puissent aussi être interrogés avec CQLinq.

Share this article