Recenzie independentă PVS-Studio (Linux, C++)

Am văzut o publicație despre faptul că PVS a învățat să analyzeze pe Linux și am decis să încerc pe proiectele mele. Iată ce a ieșit.


Cuprins

  1. Advantages
  2. Dezavantaje
  3. Concluzii
  4. Cuvânt înainte

Advantages

Asistență receptivă

Am solicitat o cheie de probă, iar în aceeași zi mi-a fost trimisă.

Documentație destul de clară

Am reușit să pornesc analizerul fără probleme majore. Există și un ghid pentru comenzile din consolă (deși aici sunt observații, vezi secțiunea Dezavantaje).

Capacitatea de analiză multiprocesare

Analizatorul are o opțiune „standard” -j, care permite analizarea în paralel în mai multe sarcini. Acest lucru economisește mult timp.

Vizualizare bună

Multe formate de ieșire diferite, de la text la o interfață web mică. Interfața web este convenabilă, concisă, cu sugestii lângă liniile din cod și legături către descrierile diagnosticelor.

Integrate ușor în construcție

Toată documentația este disponibilă pe site-ul lor, trebuie să spun doar că dacă proiectul tău este compilat cu ajutorul CMake, atunci totul este foarte simplu.

Descrieri bune ale diagnosticelor

Dacă generezi ieșirea în modul fullhtml, atunci fiecare mesaj are un link către descrierea diagnosticii, cu explicații, exemple de cod și linkuri suplimentare.

Dezavantaje

Cunoștințele insuficiente ale analizatorului în limbajul C++

Din păcate, PVS uneori greșește în sintaxă și generează mesaje false pozitive pentru coduri complet corecte.

De exemplu, există o funcție care returnează 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));
}

Da, cuvântul cheie auto poate însemna void, așa că este auto. Dar PVS a dat următoarele mesaje:

dynamic_tuple_management.hpp:29:1: eroare: V591 Funcția non-void ar trebui să returneze o valoare.
dynamic_tuple_management.hpp:29:1: eroare: V2542 Funcția cu un tip de returnare non-void ar trebui să returneze o valoare din toate căile de ieșire.

Site foarte lent

Da, în interfața web, lângă fiecare mesaj există un link către descrierea corespunzătoare a diagnosticii cu exemple. Dar atunci când dai clic pe link, trebuie să aștepți destul de mult, iar uneori este și 504 Gateway Time-out.

Language

Toate descrierile sunt disponibile în rusă, ceea ce este excelent. Dar linkurile din raport duc mereu la versiunea în engleză. Ar fi bine să existe posibilitatea de a schimba limba, astfel încât diagnosticile să poată fi vizualizate imediat în rusă. Nu am găsit o astfel de opțiune în interfață.

Incomod să lucrezi cu nivelurile diagnosticilor prin consolă

Haideți să începem cu faptul că cele două echipe utilizate (acesta este pvs-studio-analyzer și plog-converter) au formate diferite pentru atribuirea diagnosticelor.

Documentația pentru pvs-studio-analyzer spune că:

-a [MODE], --analysis-mode [MODE]
    MODE definește tipul de avertizări:
    1 - erori pe 64 de biți;
    2 - rezervat;
    4 - Analiză Generală;
    8 - Micro-optimizări;
    16 - Cerințe specifice clienților;
    32 - MISRA.
    Modurile pot fi combinate prin adunarea valorilor
    Implicit: 4

Am încercat mult timp să înțeleg unde trebuie să adaug („adding the values”) cheile. Am încercat să le enumerez prin virgulă:

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

Am încercat să specific cheia de mai multe ori:

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

Și abia apoi mi-a trecut prin cap că acestea sunt măști bitwise! Și trebuie să sumez, nu adaug valorile. De exemplu, pentru a obține diagnosticele generale, diagnosticele pentru micro-optimizări și MISRA, trebuie să le adun (4 + 8 + 32 = 44):

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

Utilizarea măștilor bitwise în interfețele utilizator este, de obicei, un comportament necorespunzător. Toate acestea ar fi putut fi adunate și în interior, și utilizatorului să i se prezinte un set de steaguri.

În plus, există o unealtă plog-converter, care generează informații ușor de citit despre analiza statică. Are alte capricii.

Documentația programului plog-converter raportează:

-a, --analyzer            Specifică analyzer(e) și nivel(uri) care vor fi
                          utilizate pentru filtrare, adică
                          'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2'
                          Implicit: GA:1,2

Aici au apărut niște „niveluri” despre care nu am mai știut nicăieri până acum, și în documentație nu am găsit nimic despre ele.

În general, nu am înțeles. De aceea am setat totul la maximum.

O mulțime de erori inutilizabile în Catch

În două din cele trei proiecte pe care le-am analizat, se folosește biblioteca de testare modulară Catch2. Și o mare parte din mesajele (!!! 90 din 138 într-unul și 297 din 344 în altul !!!) sunt de următoarea formă:

Recenzie independentă PVS-Studio (Linux, C++)

Nu ia în considerare multithreading-ul

Multe alarme fals pozitive cu variabile care aparent nu se schimbă sau bucle infinite, în timp ce lucrează cu acele variabile din fluxuri diferite, și dacă nu ar fi fost așa, testele modulare nu ar fi declanșate.

Recenzie independentă PVS-Studio (Linux, C++)

Cu toate acestea, poate oare un analist static să ia în considerare așa ceva? Nu știu.

Concluzii

PVS nu a găsit nicio eroare reală în proiectele mele deschise Burst și Proxima, precum și în proiectul de lucru pe care, din motive evidente, nu îl pot arăta. Totuși, trebuie menționat că unele neajunsuri au fost deja corectate anterior cu ajutorul Cppcheck și scan-build.

În general, impresia pe care o lasă toți acești analizatori este similară: da, captează ceva, uneori chiar ceva important, dar, în general, un compilator este suficient.

Poate (și mă bucur să cred asta), echipa noastră folosește practici de dezvoltare software care permit generarea unei cantități minime de cod de proastă calitate. Este mai bine să nu creezi probleme decât să le depășești eroic.

Așa că îmi asum libertatea de a oferi câteva sfaturi despre cum să scrii în C++ astfel încât să nu îți împuști nimeni picioarele și să nu te lovești de greble în frunte.

Folosește la maximum diagnosticele compilatorului

Echipa noastră folosește (și vă recomandă) următoarele opțiuni de compilare:

-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

Include-le în proiectul tău, vei învăța multe lucruri noi despre codul tău.

Respectă standardul

Încearcă să nu folosești lucruri dependente de platformă, dacă există analogi standard, iar dacă nu poți evita cu totul aceste lucruri, învăluie-le în blocuri speciale sub macro-uri (sau altfel) și pur și simplu nu permite compilarea codului tău în condiții neacceptate.

Respectă semantica standard a operațiunilor

Adunarea trebuie să fie adunare, înmulțirea — înmulțire, apelul de funcție — apel de funcție, copierea trebuie să copieze, mutarea — să mute, un container trebuie să fie iterabil, un iterator trebuie să aibă progresie ++ și dereferire. *Și așa mai departe, și așa mai departe.

Cred că ideea este clară. Există convenții stabilite care nu sunt obligatorii, dar pe care toți utilizatorii și cititorii codului tău se așteaptă să le vadă. Nu încerca să-i păcălești pe alții, căci te vei păcăli pe tine însuți.

Scrie cod compatibil

În primul rând, mă refer la biblioteca standard. Este foarte de dorit ca interfețele claselor și funcțiilor tale să poate fi folosite cu biblioteci standard și alte biblioteci (de exemplu, Boost).

Nu ezita să arunci o privire în interfețele STL și Boost. Cu rare excepții, acolo vei găsi exemple demne de urmat.

Folosește la maximum uneltele deschise.

Pentru aceeași analiz statică, există cel puțin două instrumente gratuite deschise care se conectează, o dată, la orice proiect cu un sistem de construire CMake.

Pentru mai multe detalii, puteți citi publicația mea recentă..

Cuvânt înainte

În cele din urmă, vreau să subliniez că nu îndemn la nesolicitarea PVS sau a altor analizatori statici. Dar vă încurajez să reflectați la cum se face că analizatorul static găsește constant erori semnificative în codul dumneavoastră.

Aceasta este doar o consecință. Trebuie să căutăm și să eliminăm cauza.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster