Progressivement et discrètement, une situation se développe lorsque la complexité de projets C ++ sérieux devient prohibitive. Malheureusement, maintenant un programmeur C ++ ne peut pas compter uniquement sur ses propres forces.
Premièrement, il y a tellement de code qu'il n'est plus possible lorsqu'il y a au moins deux programmeurs dans le projet qui connaissent tout le projet. Par exemple, le noyau Linux 1.0.0 contenait environ 176 000 lignes de code. C'est beaucoup, mais il était possible de mettre une machine à café à proximité et en quelques semaines de regarder plus ou moins tout le code et de comprendre les principes généraux de son fonctionnement. Si nous prenons le noyau Linux 5.0.0, la taille de la base de code est déjà d'environ 26 millions de lignes de code. Le code du noyau a augmenté presque 150 fois. Vous ne pouvez sélectionner que plusieurs parties du projet et participer à leur développement. Il est impossible de s'asseoir et de comprendre comment tout cela fonctionne exactement, quelles sont les relations entre les différentes sections du code.
Deuxièmement, le langage C ++ continue d'évoluer rapidement. D'une part, c'est bien, car il existe des constructions qui vous permettent d'écrire du code plus compact et sécurisé. En revanche, en raison de la rétrocompatibilité, les anciens grands projets deviennent hétérogènes. Ils entrelacent des approches anciennes et nouvelles pour écrire du code. L'analogie avec des anneaux sur une section d'un arbre prie. De ce fait, chaque année, s'immerger dans des projets écrits en C ++ devient de plus en plus difficile. Vous devez comprendre le code en même temps, à la fois écrit dans le style C avec des classes, et dans les approches modernes (lambdas, sémantique du mouvement, etc.). Il faut trop de temps pour apprendre pleinement le C ++. Mais comme il est toujours nécessaire de développer des projets, les gens commencent à écrire du code en C ++ sans avoir étudié toutes ses nuances jusqu'au bout. Cela conduit à des défauts supplémentaires, mais il est irrationnel à cause de cela de s'arrêter et d'attendre que tous les développeurs se familiarisent parfaitement avec C ++.
La situation est-elle désespérée? Non. Une nouvelle classe d'outils vient à la rescousse: les analyseurs de code statique. De nombreux programmeurs expérimentés en ce moment ont bouclé leurs lèvres, comme s'ils glissaient un citron :). Comme, nous connaissons ceux-ci votre linter ... Il y a beaucoup de messages, un peu de sens ... Oui, et quelle est cette nouvelle classe d'outils?! We linter a été lancé il y a 20 ans.
Néanmoins, j'ose affirmer qu'il s'agit précisément d'une nouvelle classe d'outils. Ce qui s'est passé il y a 10 à 20 ans n'est pas du tout les outils qui sont maintenant appelés analyseurs statiques. Tout d'abord, je ne parle pas des outils orientés sur la mise en forme du code. Ils concernent également les outils d'analyse statique, mais nous parlons maintenant d'identifier les erreurs dans le code. Deuxièmement, les outils modernes utilisent des technologies d'analyse sophistiquées, prenant en compte les interconnexions entre les différentes fonctions et exécutant en fait virtuellement certaines sections de code. Ce ne sont pas les mêmes linters de 20 ans construits sur des expressions régulières. Soit dit en passant, un analyseur statique normal
ne peut
pas du tout être effectué sur des expressions régulières. Pour rechercher des erreurs, des technologies telles que l'analyse du flux de données, l'annotation automatique des méthodes, l'exécution symbolique, etc. sont utilisées.
Ce ne sont pas des mots abstraits, mais la réalité que j'observe comme l'un des créateurs de l'outil PVS-Studio. Consultez cet
article pour voir pourquoi les analyseurs peuvent trouver des erreurs intéressantes.
Cependant, il est beaucoup plus important que les analyseurs statiques modernes aient une connaissance approfondie des modèles d'erreur. De plus, les analyseurs en savent plus que même les développeurs professionnels. Il est devenu trop difficile de prendre en compte et de se souvenir de toutes les nuances lors de l'écriture de code. Par exemple, à moins que vous ne le lisiez spécifiquement quelque part, vous ne devinerez jamais que les appels à la fonction
memset pour effacer des données privées disparaissent parfois, car du point de vue du compilateur, l'appel à la fonction
memset est redondant. En attendant, il s'agit d'un grave défaut de sécurité
CWE-14 , que l'on retrouve littéralement
partout . Ou qui, par exemple, sait ce qui est dangereux dans un tel remplissage de conteneurs?
std::vector<std::unique_ptr<MyType>> v; v.emplace_back(new MyType(123));
Je pense que tout le monde ne se rendra pas immédiatement compte qu'un tel code est potentiellement
dangereux et peut entraîner des fuites de mémoire.
En plus d'une connaissance approfondie des modèles, les analyseurs statiques sont infiniment attentifs et ne se fatiguent jamais. Par exemple, contrairement à une personne, ils ne sont pas trop paresseux pour regarder les fichiers d'en-tête pour s'assurer que
isspace et
sprintf sont de vraies fonctions, et pas des
macros folles qui gâchent tout. De tels cas démontrent l'essence de la difficulté de trouver des erreurs dans les grands projets: quelque chose change à un endroit, mais se brise à un autre.
Je suis convaincu que l'analyse statique deviendra bientôt une partie intégrante de DevOps - elle sera aussi naturelle et nécessaire que l'utilisation du système de contrôle de version. Cela se produit déjà progressivement lors de conférences consacrées au processus de développement, où l'analyse statique est de plus en plus mentionnée comme l'une des premières lignes de défense pour lutter contre les bugs.
L'analyse statique sert de sorte de filtre grossier. Il est inefficace de rechercher des erreurs stupides et des fautes de frappe à l'aide de tests unitaires ou de tests manuels. Il est beaucoup plus rapide et moins coûteux de les corriger immédiatement après avoir écrit le code, en utilisant une analyse statique pour détecter les problèmes. Cette idée, ainsi que l'importance d'une utilisation régulière de l'analyseur, sont bien décrites dans l'article «
Intégrer l'analyse statique dans le processus, et ne pas chercher de bugs avec ».
Quelqu'un peut dire que les outils spéciaux ne servent à rien, car le compilateur apprend également à effectuer de telles vérifications statiques. Oui. Cependant, les analyseurs statiques ne restent naturellement pas immobiles et comment les outils spécialisés surpassent les compilateurs. Par exemple, chaque fois que nous vérifions LLVM, nous y trouvons des
erreurs en utilisant PVS-Studio.
Le monde offre un grand nombre d'outils pour l'analyse de code statique. Comme on dit,
choisissez à votre goût. Vous voulez trouver beaucoup d'erreurs et de vulnérabilités potentielles même au stade de l'écriture de code? Utilisez des analyseurs de code statique et améliorez la qualité de votre base de code!

Si vous souhaitez partager cet article avec un public anglophone, veuillez utiliser ce lien: Andrey Karpov.
Pourquoi l'analyse statique peut améliorer une base de code C ++ complexe