J'ai vu la publication que PVS a appris à analyser sous Linux et j'ai décidé d'essayer ses projets. Et c'est ce qui en est sorti.
Table des matières
- Avantages
- Inconvénients
- Résumé
- Postface
Support réactif
J'ai demandé une clé d'essai, ils me l'ont envoyée le même jour.
Documentation suffisamment claire
Il a été possible de démarrer l'analyseur sans aucun problème. L'aide pour les commandes de la console est également disponible (bien qu'il y ait des plaintes, voir la section Contre ).
Capacité d'analyse multithread
L'analyseur possède une option «standard» -j
, qui permet d'analyser en parallèle dans plusieurs tâches. Cela fait gagner beaucoup de temps.
Bonne visualisation
De nombreux formats de sortie différents, du texte au petit museau Web. La face Web est pratique, concise, avec des conseils à côté des lignes du code et des liens vers les descriptions des diagnostics .
Intégration facile à l'assemblage
Toute la documentation est sur leur site web, je peux seulement dire que si votre projet est construit en utilisant CMake, alors tout est très simple.
Bonnes descriptions diagnostiques
Si vous générez une sortie en mode fullhtml
, chaque message contient un lien vers une description du diagnostic, avec des explications, des exemples de code et des liens supplémentaires.
Ignorance de l'analyseur de langage C ++
Malheureusement, PVS se trompe parfois dans la syntaxe et génère de faux messages positifs avec un code parfaitement correct.
Par exemple, il existe une fonction qui renvoie void
:
template <typename T> auto copy (const void * source, void * destination) -> std::enable_if_t < std::is_copy_constructible<T>::value > { new (destination) T(*static_cast<const T *>(source)); }
Oui, le mot-clé auto
peut signifier void
, c'est pourquoi auto . Mais PVS a émis ces messages:
dynamic_tuple_management.hpp:29:1: error: V591 Non-void function should return a value. dynamic_tuple_management.hpp:29:1: error: V2542 Function with a non-void return type should return a value from all exit paths.
Site très lent
Oui, dans le museau Web à côté de chaque message, il y a un lien vers la description correspondante du diagnostic avec des exemples. Mais lorsque vous cliquez sur le lien, vous devez attendre assez longtemps, et parfois cela arrive 504 Gateway Time-out .
La langue
Toutes les descriptions sont en russe, c'est super. Mais les liens du rapport mènent toujours à la version anglaise. Ce serait bien de pouvoir changer de langue pour que vous puissiez voir les diagnostics immédiatement en russe. Je n'ai pas trouvé une telle opportunité dans l'interface.
Inconvénient de travailler avec des niveaux de diagnostic via la console
Pour commencer, les deux commandes utilisées ( pvs-studio-analyzer
et plog-converter
) ont des formats de travail de diagnostic différents.
L'aide de pvs-studio-analyzer
lit comme suit:
-a [MODE], --analysis-mode [MODE] MODE defines the type of warnings: 1 - 64-bit errors; 2 - reserved; 4 - General Analysis; 8 - Micro-optimizations; 16 - Customers Specific Requests; 32 - MISRA. Modes can be combined by adding the values Default: 4
Pendant longtemps, j'ai essayé de comprendre où ajouter ("ajouter les valeurs") des clés. J'ai essayé de lister avec une virgule:
pvs-studio-analyzer analyze ... -a 1,4,16
J'ai essayé d'enregistrer la clé plusieurs fois:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16
Et c'est seulement alors que j'ai réalisé que ce sont des masques de bits! Et vous devez résumer , pas ajouter de valeurs. Par exemple, pour obtenir des diagnostics généraux, des diagnostics pour les microoptimisations et MISRA, vous devez les additionner (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44
L'utilisation de masques de bit dans les interfaces utilisateur est généralement une mauvaise idée. Tout cela pourrait être résumé à l'intérieur, et l'utilisateur a défini un ensemble de drapeaux.
En outre, il existe également l' plog-converter
, qui génère des informations lisibles par l'homme sur l'analyse statique. Elle a d'autres problèmes.
Aide pour les rapports du programme plog-converter
:
-a, --analyzer Specifies analyzer(s) and level(s) to be used for filtering, ie 'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2' Default: GA:1,2
Une sorte de «niveaux» est apparu ici, qui n'avait jamais été vu auparavant, et je n'ai rien trouvé à leur sujet dans la documentation.
En général, ce n'est pas clair. Par conséquent, j'ai tout réglé au maximum.
Un tas de stupides jurons à Catch
Deux des trois projets que j'ai analysés utilisent la bibliothèque de tests unitaires Catch2 . Et la part du lion des messages (!!! 90 sur 138 dans un et 297 sur 344 dans un autre !!!) ont la forme suivante:

Ne considère pas le multithreading
Il existe de nombreux faux positifs sur les variables supposées immuables ou les boucles infinies, alors que travailler avec ces variables provient de différents threads, et si ce n'était pas le cas, les tests unitaires ne fonctionneraient pas.

Cependant, un analyseur statique peut-il prendre cela en compte? Je ne sais pas.
PVS n'a pas trouvé une seule véritable erreur dans mes projets ouverts Burst et Proxima , ainsi que dans un projet de travail, que je, pour des raisons évidentes, ne peux pas présenter. Certes, il convient de garder à l'esprit que certains défauts ont déjà été détectés et corrigés plus tôt à l'aide de Cppcheck et de scan-build
.
En général, l'impression de tous ces analyseurs est à peu près la même: oui, ils captent quelque chose, parfois même quelque chose d'important, mais dans l'ensemble le compilateur suffit.
Il est possible (et personnellement, je suis heureux de le penser) que notre équipe utilise de telles pratiques de développement logiciel qui nous permettent de générer le minimum de merde. Mieux vaut ne pas créer de problèmes que de les surmonter héroïquement.
Par conséquent, je me permets de donner quelques conseils sur la façon d’écrire en C ++ de manière à ne tirer sur les jambes de personne et à ne pas ratisser sur le front.
Utilisez les diagnostics du compilateur au maximum
Notre équipe utilise (et vous conseille) les options de compilation suivantes:
-Werror -Wall -Wextra -Wpedantic -Wcast-align -Wcast-qual -Wconversion -Wctor-dtor-privacy -Wenum-compare -Wfloat-equal -Wnon-virtual-dtor -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wsign-conversion -Wsign-promo
Incluez-les dans votre projet, apprenez beaucoup sur votre code.
Respectez la norme
Essayez de ne pas utiliser de choses dépendantes de la plate-forme s'il existe des analogues standard, et si vous ne pouvez pas vous en passer, enveloppez-les dans des blocs spéciaux pour les prises de vue macro (ou autre) et ne nous laissez pas compiler votre code dans des conditions non prises en charge.
Respectez la sémantique de fonctionnement standard
L'addition doit être l'addition, la multiplication par multiplication, l'appel de fonction par appel de fonction, la copie doit copier, le transfert doit être transféré, le conteneur doit être itérable, l'itérateur doit avoir la promotion ++
et la déréférence *
. Et ainsi de suite et ainsi de suite.
Je pense que l'idée est claire. Il existe des accords établis qui ne sont pas contraignants mais que tous les utilisateurs et lecteurs de votre code s'attendent à voir. N'essayez pas de déjouer les autres, ou bien de vous surpasser.
Écrire un code compatible
Tout d'abord, je veux dire la bibliothèque standard. Il est hautement souhaitable que les interfaces de vos classes et fonctions puissent être utilisées avec des bibliothèques standard et autres (par exemple, Bust).
N'hésitez pas à jeter un œil aux interfaces STL et Boost. À de rares exceptions près, vous y verrez un digne modèle.
Tirez le meilleur parti des outils ouverts
Pour la même analyse statique, il existe au moins deux outils libres ouverts qui sont connectés à n'importe quel projet avec le système de construction CMake au détriment du "temps".
Vous pouvez en savoir plus à ce sujet dans ma récente publication .
En conclusion, je souligne que je n'encourage pas à ne pas utiliser PVS ou tout autre analyseur statique. Mais je vous invite à réfléchir à la façon dont il s'est avéré que l'analyseur statique trouve constamment des erreurs importantes dans votre code.
Ce n'est qu'une conséquence. Il est nécessaire de rechercher et d'éliminer la cause.