Examen indépendant de PVS-Studio (Linux, C++)

J'ai vu une publication que PVS avait appris à analyser sous Linux et j'ai décidé de l'essayer sur mes propres projets. Et voilà ce qui en est ressorti.


Teneur

  1. Avantages
  2. Moins
  3. Les résultats de
  4. Postface

Avantages

Support réactif

J'ai demandé une clé d'essai et ils me l'ont envoyée le même jour.

Documentation assez claire

Nous avons réussi à lancer l'analyseur sans aucun problème. Une aide pour les commandes de la console est également disponible (bien qu'il y ait quelques plaintes ici, voir la section Moins).

Possibilité d'analyse multithread

L'analyseur dispose d'une option "standard" -j, permettant d'effectuer des analyses en parallèle dans plusieurs tâches. Cela fait gagner beaucoup de temps.

Bonne visualisation

De nombreux formats de sortie différents, du texte à une petite muselière Web. L'interface Web est pratique, concise, avec des astuces à côté des lignes du code et des liens vers des descriptions de diagnostic..

Intégration facile dans l'assemblage

Toute la documentation est sur leur site Web, je peux seulement dire que si votre projet est construit à l'aide de CMake, alors tout est très simple.

Bonnes descriptions de diagnostic

Si vous générez une sortie en mode fullhtml, alors chaque message comporte un lien vers une description de diagnostic, avec des explications, des exemples de code et des liens supplémentaires.

Moins

Méconnaissance du langage C++ par l'analyseur

Malheureusement, PVS fait parfois des erreurs de syntaxe et génère des messages faussement positifs lorsque le code est tout à fait 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, mot-clé auto Peut signifier void, c'est à ça que ça sert auto. Mais PVS a produit les messages suivants :

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 l'interface Web, à côté de chaque message, vous trouverez un lien vers la description du diagnostic correspondante avec des exemples. Mais quand on clique sur un lien, il faut attendre assez longtemps, et parfois ça arrive 504 passerelle Time-out.

Langue

Toutes les descriptions sont en russe, ce qui est génial. Mais les liens du rapport mènent toujours à la version anglaise. Ce serait bien de pouvoir changer de langue afin que vous puissiez visualiser immédiatement les diagnostics en russe. Je n'ai pas trouvé une telle option dans l'interface.

Il n'est pas pratique de travailler avec des niveaux de diagnostic via la console

Commençons par le fait que les deux commandes utilisées (cette pvs-studio-analyzer и plog-converter) différents formats pour spécifier les diagnostics.

De l'aide pour pvs-studio-analyzer lit :

-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

J'ai passé beaucoup de temps à essayer de savoir où aller ajouter (« ajouter les valeurs »). J'ai essayé de les lister séparés par des virgules :

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 à ce moment-là que j’ai réalisé qu’il s’agissait de petits masques ! Et tu as besoin résumerEt ce n'est pas ajouter significations. Par exemple, pour obtenir des diagnostics généraux, des diagnostics de micro-optimisations et MISRA, il faut les résumer (4 + 8 + 32 = 44) :

pvs-studio-analyzer analyze ... -a 44

L’utilisation de masques de bits dans les interfaces utilisateur est généralement une mauvaise forme. Tout cela pourrait être résumé en interne et un ensemble d'indicateurs pourrait être défini pour l'utilisateur.

De plus, il existe également un utilitaire plog-converter, qui génère des informations d'analyse statique lisibles par l'homme. Elle a d'autres problèmes.

Aide pour le programme plog-converter rapports:

-a, --analyzer            Specifies analyzer(s) and level(s) to be
                          used for filtering, i.e.
                          'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
                          Default: GA:1,2

Certains « niveaux » sont apparus ici qui n'existaient pas auparavant, et je n'ai rien trouvé non plus à leur sujet dans la documentation.

En général, ce n'est pas clair. C'est pourquoi j'ai tout réglé au maximum.

Un tas de jurons stupides sur Catch

Deux des trois projets que j'ai analysés utilisent une bibliothèque de tests unitaires Catch2. Et la part du lion des messages (!!! 90 sur 138 dans l'un et 297 sur 344 dans l'autre !!!) ont la forme suivante :

Examen indépendant de PVS-Studio (Linux, C++)

Ne prend pas en compte le multithreading

Il existe de nombreux faux positifs concernant des variables soi-disant immuables ou des boucles sans fin, alors que le travail avec ces variables s'effectue à partir de différents threads, et si ce n'était pas le cas, les tests unitaires ne fonctionneraient pas.

Examen indépendant de PVS-Studio (Linux, C++)

Cependant, un analyseur statique peut-il même en tenir compte ? Je ne sais pas.

Les résultats de

PVS n'a trouvé aucun bug réel dans mes projets open source Burst и Proxima, ainsi que dans un projet de travail que, pour des raisons évidentes, je ne peux pas présenter. Certes, il convient de garder à l'esprit que certaines lacunes ont déjà été détectées et corrigées plus tôt en utilisant Cppcheck и scan-build.

En général, l'impression de tous ces analyseurs est à peu près la même : oui, ils détectent quelque chose, parfois même quelque chose d'important, mais dans l'ensemble, le compilateur suffit.

Il est possible (et j'aime personnellement le penser) que notre équipe utilise des pratiques de développement logiciel qui nous permettent de générer un minimum de code merdique. Il vaut mieux ne pas créer de problèmes plutôt 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 personne dans les jambes ou à ne frapper personne au front avec un râteau.

Tirez le meilleur parti des diagnostics du compilateur

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

Activez-les dans votre projet et apprenez-en beaucoup sur votre code.

S'en tenir à la norme

Essayez de ne pas utiliser d'éléments dépendant de la plate-forme s'il existe des analogues standard, et si vous ne pouvez absolument pas vous en passer, enveloppez-les dans des blocs spéciaux pour les macros (ou autre chose) et ne laissez tout simplement pas votre code être compilé dans des conditions non prises en charge.

S'en tenir à la sémantique d'opération standard

L'addition doit être une addition, la multiplication doit être une multiplication, l'appel de fonction doit être un appel de fonction, la copie doit être une copie, le report doit être le report, le conteneur doit être itérable, l'itérateur doit avoir une promotion ++ et déréférencement *. Et ainsi de suite.

Je pense que l'idée est claire. Il existe des conventions établies qui ne sont pas contraignantes, mais que tous les utilisateurs et lecteurs de votre code s'attendent à voir. N'essayez pas de déjouer les autres, sinon vous vous déjouerez vous-même.

Écrire du 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 standards et autres (par exemple, Boost).

N'hésitez pas à jeter un œil aux interfaces STL et Boost. À de rares exceptions près, vous y verrez un modèle digne de ce nom.

Tirez le meilleur parti des outils open source

Pour la même analyse statique, il existe au moins deux outils gratuits et ouverts qui peuvent être connectés une seule fois à n'importe quel projet avec le système de build CMake.

Vous pouvez en savoir plus à ce sujet dans ma récente publication.

Postface

Enfin, je voudrais souligner que je ne préconise pas de ne pas utiliser PVS ou tout autre analyseur statique. Mais je vous encourage à réfléchir à la façon dont il se fait que l'analyseur statique trouve constamment des erreurs importantes dans votre code.

Ce n'est qu'une conséquence. Nous devons rechercher et éliminer la cause.

Source: habr.com

Ajouter un commentaire