Ich habe die Veröffentlichung gesehen, dass PVS nun in der Lage ist, unter Linux zu analysieren, und wollte es an meinen Projekten ausprobieren. Und das ist das Ergebnis.
Inhalt
Reaktionsschneller Support
Ich habe einen Testschlüssel angefordert, und am selben Tag wurde er mir zugesendet.
Eher verständliche Dokumentation
Der Analysator ließ sich ohne besondere Probleme starten. Die Hilfe zu den Konsolenbefehlen ist ebenfalls vorhanden (auch wenn es hier Beschwerden gibt, siehe Abschnitt ).
Möglichkeit zur mehrthreadigen Analyse
Der Analysator hat die "Standard"-Option -j, die es ermöglicht, die Analyse parallel in mehreren Aufgaben durchzuführen. Das spart erheblich Zeit.
Gute Visualisierung
Viele verschiedene Ausgabeformate, von Text bis zu einer kleinen Web-Oberfläche. .
Einfache Integration in den Build
Die gesamte Dokumentation ist auf ihrer Website verfügbar, ich kann nur sagen, dass es sehr einfach ist, wenn Ihr Projekt mit CMake gebaut wird.
Gute Beschreibungen der Diagnosen
Wenn der Output im Modus fullhtml, generiert wird, hat jede Nachricht einen Link zur Diagnosebeschreibung, mit Erklärungen, Codebeispielen und zusätzlichen Links.
Unkenntnis des C++-Analysators
Leider macht PVS manchmal Syntaxfehler und generiert falsch-positive Meldungen für völlig korrekten Code.
Zum Beispiel gibt es eine Funktion, die zurückgibt void:
template
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 bedeuten void, denn es ist so auto. Aber PVS gab 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 Website
Ja, in der Web-Oberfläche gibt es neben jeder Nachricht einen Link zur entsprechenden Diagnosebeschreibung mit Beispielen. Aber beim Klicken auf den Link muss man ziemlich lange warten, und manchmal kommt es auch zu .
Sprache
Alle Beschreibungen sind auf Russisch, das ist großartig. Aber die Links aus dem Bericht führen immer zur englischen Version. Es wäre schön, die Möglichkeit zu haben, die Sprache umzuschalten, damit die Diagnosen sofort auf Russisch angezeigt werden können. Eine solche Möglichkeit habe ich in der Oberfläche nicht gefunden.
Es ist umständlich, mit den Diagnosestufen über die Konsole zu arbeiten
Fangen wir damit an, dass die beiden verwendeten Befehle (dies ist pvs-studio-analyzer und plog-converter) unterschiedliche Formate für die Diagnosen haben.
Die Hilfe zu pvs-studio-analyzer lautet:
-a [MODE], --analysis-mode [MODE]
MODE definiert die Art der Warnungen:
1 - 64-Bit-Fehler;
2 - reserviert;
4 - Allgemeine Analyse;
8 - Mikro-Optimierungen;
16 - Kundenspezifische Anforderungen;
32 - MISRA.
Modi können kombiniert werden, indem die Werte
addiert werden.
Standard: 4Ich habe lange versucht zu verstehen, wo ich hinzufügen („adding the values“) die Schlüssel einfügen soll. Ich habe versucht, sie durch Kommas zu trennen:
pvs-studio-analyzer analyze ... -a 1,4,16Ich habe versucht, den Schlüssel mehrmals zu schreiben:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16Und erst dann ist mir eingefallen, dass es sich um Bitmasken handelt! Und dass ich die Werte addieren, nicht hinzufügen muss. Zum Beispiel, um die allgemeinen Diagnosen, die Diagnosen zu Mikro-Optimierungen und MISRA zu erhalten, muss ich sie addieren (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44Die Verwendung von Bitmasken in Benutzeroberflächen ist in der Regel unangebracht. Man hätte alles auch intern summieren können und dem Benutzer ein Satz von Flags bereitstellen.
Außerdem gibt es noch ein Dienstprogramm plog-converter, das menschenlesbare Informationen über die statische Analyse generiert. Es hat andere Eigenheiten.
Die Hilfe des Programms plog-converter gibt an:
-a, --analyzer Gibt die Analyzer und Level an,
die zur Filterung verwendet werden,
d.h.
'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
Standard: GA:1,2Hier sind irgendwelche «Level» aufgetaucht, die es vorher nirgendwo gab, und ich habe in der Dokumentation auch nichts darüber gefunden.
Im Allgemeinen ist es unklar. Daher habe ich alles auf maximum gesetzt.
Eine Menge sinnloser Fehlermeldungen in Catch
In zwei von drei Projekten, die ich analysiert habe, wird die Bibliothek für Modultests verwendet, . Und der Löwenanteil der Meldungen (!!! 90 von 138 in einem und 297 von 344 in einem anderen !!!) sieht wie folgt aus:

Berücksichtigt nicht die Multithreadedität
Es gibt viele falsche positives Ergebnisse über angeblich unveränderte Variablen oder Endlosschleifen, obwohl die Arbeit mit diesen Variablen aus verschiedenen Threads erfolgt, und wenn dem nicht so wäre, würden die Modultests nicht auslösen.

Aber kann ein statischer Analyzer sowas überhaupt berücksichtigen? Ich weiß es nicht.
PVS hat in meinen öffentlichen Projekten und , sowie in einem Arbeitsprojekt, das ich aus verständlichen Gründen nicht vorzeigen kann, keinen einzigen echten Fehler gefunden. Allerdings sollte man bedenken, dass einige Mängel bereits früher mit Hilfe von und .
Insgesamt ist der Eindruck von all diesen Analysewerkzeugen ungefähr derselbe: Ja, sie erfassen etwas, manchmal sogar etwas Wichtiges, aber im Großen und Ganzen reicht der Compiler aus.
Vielleicht (und es freut mich, so zu denken), verwendet unser Team solche Praktiken der Softwareentwicklung, die es ermöglichen, die Menge an schlechtem Code zu minimieren. Es ist besser, keine Probleme zu schaffen, als sie heldenhaft zu überwinden.
Deshalb erlaube ich mir, einige Ratschläge zu geben, wie man in C++ programmiert, ohne dabei jemandem in die Beine zu schießen oder mit der Harke auf die Stirn zu bekommen.
Nutzen Sie die Compiler-Diagnosen maximal aus
Unser Team verwendet (und empfiehlt Ihnen) 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-promoIntegrieren Sie sie in Ihr Projekt, Sie werden viel Neues über Ihren Code erfahren.
Halten Sie sich an den Standard
Versuchen Sie, plattformabhängige Dinge zu vermeiden, wenn es Standardäquivalente gibt. Wenn es jedoch unumgänglich ist, wickeln Sie sie in spezielle Blöcke unter Makros (oder auf andere Weise) und lassen Sie Ihren Code nicht in nicht unterstützten Bedingungen kompilieren.
Halten Sie sich an die standardmäßige Semantik von Operationen
Addition sollte Addition sein, Multiplikation – Multiplikation, Funktionsaufruf – Funktionsaufruf, Kopieren sollte kopieren, Verschieben – verschieben, ein Container sollte iterierbar sein, ein Iterator sollte Fortschritt haben ++ und Dereferenzierung. *. Und so weiter, und so weiter.
Ich denke, der Gedanke ist klar. Es gibt etablierte Vereinbarungen, die nicht verbindlich sind, aber die alle Benutzer und Leser Ihres Codes erwarten. Versuchen Sie nicht, andere zu überlisten, sonst überlisten Sie sich selbst.
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 (zum Beispiel Boost) verwendet werden können.
Scheuen Sie sich nicht, die Schnittstellen von STL und Boost zu konsultieren. Mit wenigen Ausnahmen finden Sie dort ein gutes Vorbild.
Nutzen Sie offene Werkzeuge maximal aus.
Für die statische Analyse gibt es mindestens zwei kostenlose Open-Source-Tools, die einmalig mit jedem Projekt mit CMake-Bau-System verbunden werden können.
.
Ich möchte abschließend betonen, dass ich nicht dazu aufrufe, PVS oder andere statische Analysewerkzeuge nicht zu verwenden. Aber ich fordere dazu auf, darüber nachzudenken, wie es dazu kam, dass der statische Analysewerkzeug ständig erhebliche Fehler in Ihrem Code findet.
Das ist nur eine Folge. Man muss die Ursache suchen und beseitigen.
Quelle: habr.com
