Unabhängige Überprüfung von PVS-Studio (Linux, C ++)

Ich sah die Veröffentlichung, die PVS unter Linux analysieren lernte, und beschloss, seine Projekte auszuprobieren. Und das ist es, was daraus wurde.



Inhalt


  1. Vorteile
  2. Nachteile
  3. Zusammenfassung
  4. Nachwort


Vorteile


Reaktionsschnelle Unterstützung


Ich habe einen Testschlüssel angefordert, den sie mir am selben Tag geschickt haben.


Klar genug Dokumentation


Der Analysator konnte problemlos gestartet werden. Hilfe für Konsolenbefehle ist ebenfalls verfügbar (obwohl es Beschwerden gibt, siehe Abschnitt Nachteile ).


Multithread-Analysefunktion


Der Analysator verfügt über eine Standardoption -j , mit der mehrere Aufgaben parallel analysiert werden können. Das spart viel Zeit.


Gute Visualisierung


Viele verschiedene Ausgabeformate, vom Text bis zur kleinen Webmündung. Das Webface ist praktisch, übersichtlich und enthält Tipps neben den Zeilen im Code sowie Links zu Beschreibungen der Diagnose .


Einfache Montageintegration


Die gesamte Dokumentation befindet sich auf ihrer Website. Ich kann nur sagen, dass alles sehr einfach ist, wenn Ihr Projekt mit CMake erstellt wird.


Gute diagnostische Beschreibungen


Wenn Sie eine Ausgabe im fullhtml Modus generieren, enthält jede Nachricht einen Link zu einer Beschreibung der Diagnose mit Erläuterungen, Codebeispielen und zusätzlichen Links.



Nachteile


Ignoranz von C ++ Language Analyzer


Leider ist PVS manchmal in der Syntax fehlerhaft und generiert falsch positive Nachrichten mit perfekt korrektem Code.


Zum Beispiel gibt es eine Funktion, die void zurückgibt:


 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)); } 

Ja, das Schlüsselwort auto kann void bedeuten, deshalb auto . PVS gab jedoch folgende Meldungen aus:


 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. 

Sehr langsame Seite


Ja, in der Web-Schnauze neben jeder Nachricht befindet sich ein Link zur entsprechenden Beschreibung der Diagnose mit Beispielen. Wenn Sie jedoch auf den Link klicken, müssen Sie lange genug warten, und manchmal kommt es zu einem 504 Gateway Timeout .


Sprache


Alle Beschreibungen sind in russischer Sprache, das ist großartig. Die Links aus dem Bericht führen jedoch immer zur englischen Version. Es wäre schön, die Sprache wechseln zu können, damit Sie die Diagnose sofort auf Russisch anzeigen können. Ich habe eine solche Möglichkeit in der Benutzeroberfläche nicht gefunden.


Es ist unpraktisch, mit Diagnoseebenen über die Konsole zu arbeiten


Zunächst haben die beiden verwendeten Befehle ( pvs-studio-analyzer und plog-converter ) unterschiedliche Diagnosejobformate.


Die Hilfe für pvs-studio-analyzer lautet:


 -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 

Lange Zeit habe ich versucht zu verstehen, wo Schlüssel hinzugefügt werden sollen ("Hinzufügen der Werte"). Versucht, mit einem Komma aufzulisten:


 pvs-studio-analyzer analyze ... -a 1,4,16 

Ich habe mehrmals versucht, den Schlüssel zu registrieren:


 pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16 

Und erst dann wurde mir klar, dass dies Bitmasken sind! Und Sie müssen zusammenfassen , keine Werte hinzufügen . Um beispielsweise eine allgemeine Diagnose, eine Diagnose für Mikrooptimierungen und MISRA zu erhalten, müssen Sie diese summieren (4 + 8 + 32 = 44):


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

Die Verwendung von Bitmasken in Benutzeroberflächen ist normalerweise eine schlechte Idee. All dies könnte im Inneren zusammengefasst werden, und der Benutzer setzte eine Reihe von Flags.


Darüber hinaus gibt es das plog-converter , das lesbare Informationen zur statischen Analyse generiert. Sie hat andere Probleme.


Hilfe für die plog-converter Programmberichte:


 -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 

Hier tauchten einige „Levels“ auf, die noch nie zuvor gesehen worden waren, und ich fand auch nichts darüber in der Dokumentation.


Im Allgemeinen ist es nicht klar. Deshalb habe ich alles auf das Maximum gesetzt.


Ein Haufen dummer Flüche auf Catch


Zwei der drei von mir analysierten Projekte verwenden die Catch2- Unit-Testing- Bibliothek . Und der Löwenanteil der Nachrichten (!!! 90 von 138 in einer und 297 von 344 in einer anderen !!!) hat die folgende Form:


Catch2


Berücksichtigt Multithreading nicht


Es gibt viele Fehlalarme bei vermeintlich unveränderlichen Variablen oder Endlosschleifen, während die Arbeit mit diesen Variablen aus verschiedenen Threads stammt. Wenn dies nicht der Fall wäre, würden Unit-Tests nicht funktionieren.


Multithreading


Kann ein statischer Analysator dies jedoch überhaupt berücksichtigen? Weiß nicht.



Zusammenfassung


PVS hat in meinen offenen Projekten Burst und Proxima sowie in einem Arbeitsentwurf, den ich aus offensichtlichen Gründen nicht vorlegen kann, keinen einzigen wirklichen Fehler gefunden. Es ist zu beachten, dass einige Fehler bereits früher mit Cppcheck und scan-build erkannt und behoben wurden.


Im Allgemeinen ist der Eindruck all dieser Analysatoren ungefähr gleich: Ja, sie erfassen etwas, manchmal sogar etwas Wichtiges, aber im Großen und Ganzen reicht der Compiler aus.


Es ist möglich (und ich persönlich freue mich darüber), dass unser Team solche Softwareentwicklungspraktiken verwendet, die es uns ermöglichen, die minimale Menge an Scheiße zu generieren. Es ist besser, keine Probleme zu schaffen, als sie heldenhaft zu überwinden.


Daher erlaube ich mir, einige Ratschläge zu geben, wie man in C ++ so schreibt, dass niemand in die Beine schießt und nicht auf die Stirn harkt.


Verwenden Sie die Compiler-Diagnose maximal


Unser Team verwendet (und berät Sie) die folgenden Kompilierungsoptionen:


 -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 

Nehmen Sie sie in Ihr Projekt auf und lernen Sie viel über Ihren Code.


Halten Sie sich an den Standard


Versuchen Sie, keine plattformabhängigen Dinge zu verwenden, wenn es Standardanaloga gibt, und wenn Sie überhaupt nicht darauf verzichten können, wickeln Sie sie in spezielle Blöcke für Makros (oder irgendwie) und lassen Sie uns Ihren Code nicht unter nicht unterstützten Bedingungen kompilieren.


Halten Sie sich an die Semantik der Standardoperation


Addition muss Addition sein, Multiplikation durch Multiplikation, Funktionsaufruf durch Funktionsaufruf, Kopie muss kopieren, Übertragung muss übertragen werden, der Container muss iterierbar sein, der Iterator muss ++ Promotion und Dereferenzierung * . Und so weiter und so fort.


Ich denke, die Idee ist klar. Es gibt Vereinbarungen, die nicht bindend sind, die aber alle Benutzer und Leser Ihres Codes erwarten. Versuchen Sie nicht, andere zu überlisten oder sich selbst zu überlisten.


Schreiben Sie kompatiblen Code


Zunächst meine ich die Standardbibliothek. Es ist sehr wünschenswert, dass die Schnittstellen Ihrer Klassen und Funktionen mit Standard- und anderen Bibliotheken (z. B. Bust) verwendet werden können.


Schauen Sie sich die STL- und Boost-Schnittstellen an. Mit seltenen Ausnahmen sehen Sie dort ein würdiges Vorbild.


Machen Sie das Beste aus offenen Werkzeugen


Für dieselbe statische Analyse gibt es mindestens zwei offene freie Tools, die auf Kosten der "Zeit" mit jedem Projekt mit dem CMake-Build-System verbunden sind.


Sie können mehr darüber in meiner jüngsten Veröffentlichung lesen .



Nachwort


Abschließend betone ich, dass ich nicht dränge, kein PVS oder andere statische Analysegeräte zu verwenden. Ich fordere Sie jedoch dringend auf, darüber nachzudenken, wie sich herausstellte, dass der statische Analysator ständig erhebliche Fehler in Ihrem Code findet.


Dies ist nur eine Konsequenz. Es ist notwendig, die Ursache zu suchen und zu beseitigen.

Source: https://habr.com/ru/post/de463027/


All Articles