Zatražio sam probni ključ i poslali su mi ga isti dan.
Prilično jasna dokumentacija
Uspjeli smo pokrenuti analizator bez ikakvih problema. Dostupna je i pomoć za komande konzole (iako ovdje ima nekih pritužbi, pogledajte odjeljak Minusy).
Mogućnost višenitne analize
Analizator ima "standardnu" opciju -j, što omogućava da se analiza provodi paralelno u nekoliko zadataka. Ovo štedi mnogo vremena.
Nažalost, PVS ponekad pravi sintaksičke greške i generiše lažno pozitivne poruke kada je kod potpuno ispravan.
Na primjer, postoji funkcija koja vraća 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 je ključna riječ auto Može značiti void, za to je auto. Ali PVS je proizveo sljedeće poruke:
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.
Veoma spora stranica
Da, u web sučelju pored svake poruke nalazi se link na odgovarajući dijagnostički opis s primjerima. Ali kada kliknete na link, morate čekati prilično dugo, a ponekad se i dogodi 504 Gateway Time-out.
Jezik
Svi opisi su na ruskom, što je odlično. Ali linkovi iz izvještaja uvijek vode do engleske verzije. Bilo bi lijepo da možete promijeniti jezik tako da možete odmah vidjeti dijagnostiku na ruskom. Nisam našao takvu opciju u interfejsu.
Nezgodno je raditi sa dijagnostičkim nivoima preko konzole
Počnimo s činjenicom da su dvije korištene naredbe (ovo pvs-studio-analyzer и plog-converter) različiti formati za specificiranje dijagnostike.
Pomoć za pvs-studio-analyzer glasi:
-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
Proveo sam dugo pokušavajući da shvatim gde da idem add („dodavanje vrijednosti“). Pokušao sam da ih navedem odvojene zarezima:
pvs-studio-analyzer analyze ... -a 1,4,16
Pokušao sam nekoliko puta registrirati ključ:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16
I tek tada sam shvatio da su to bile bitne maske! I treba ti sumirati, a ne add značenja. Na primjer, da biste dobili opću dijagnostiku, dijagnostiku za mikrooptimizacije i MISRA, trebate ih sumirati (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44
Upotreba bitmaski u korisničkim sučeljima je općenito loša forma. Sve ovo se može interno sažeti, a korisniku se može postaviti set zastavica.
Osim toga, tu je i uslužni program plog-converter, koji generiše informacije statičke analize čitljive za ljude. Ona ima drugih problema.
Pomoć za program plog-converter izvještaji:
-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
Ovdje su se pojavili neki "nivoi" kojih prije nije bilo, a ni u dokumentaciji nisam našao ništa o njima.
Generalno, nije jasno. Zato sam sve postavio na maksimum.
Gomila glupih psovki na Catchu
Dva od tri projekta koja sam analizirao koriste biblioteku za testiranje jedinica Catch2. A lavovski dio poruka (!!! 90 od 138 u jednoj i 297 od 344 u drugoj!!!) ima sljedeći oblik:
Ne uzima u obzir multithreading
Postoji mnogo lažnih pozitivnih rezultata o navodno nepromjenjivim varijablama ili beskonačnim petljama, dok se rad s tim varijablama odvija iz različitih niti, a da to nije tako, jedinični testovi ne bi radili.
Međutim, može li statički analizator to uopće uzeti u obzir? Ne znam.
PVS nije pronašao nikakve prave greške u mojim projektima otvorenog koda Burst и Sljedeći, kao i u radnom nacrtu, koji iz očiglednih razloga ne mogu predstaviti. Istina, vrijedi imati na umu da su neki nedostaci već uhvaćeni i ispravljeni ranije korištenjem Cppcheck и scan-build.
Općenito, utisak sa svih ovih analizatora je približno isti: da, uhvate nešto, ponekad čak i nešto važno, ali generalno kompajler je dovoljan.
Moguće je (a ja lično tako mislim) da naš tim koristi prakse razvoja softvera koje nam omogućavaju da generišemo minimalnu količinu usranog koda. Bolje je ne stvarati probleme nego ih herojski prevazilaziti.
Stoga, uzimam sebi slobodu da dam nekoliko savjeta kako pisati na C++-u tako da nikome ne pucam u noge i ne udaram grabljama u čelo.
Maksimalno iskoristite dijagnostiku kompajlera
Naš tim koristi (i savjetuje vam) sljedeće opcije kompilacije:
Omogućite ih u svom projektu i naučite mnogo o svom kodu.
Držite se standarda
Pokušajte ne koristiti stvari zavisne od platforme ako postoje standardni analogi, a ako apsolutno ne možete bez njih, umotajte ih u posebne blokove za makroe (ili nešto drugo) i jednostavno ne dopustite da se vaš kod kompajlira pod nepodržanim uvjetima.
Držite se standardne semantike operacija
Zbrajanje mora biti sabiranje, množenje mora biti množenje, poziv funkcije mora biti poziv funkcije, kopija mora biti kopija, prijenos mora biti prijenos, kontejner mora biti iterable, iterator mora imati promociju ++ i dereferenciranje *. I tako dalje i tako dalje.
Mislim da je ideja jasna. Postoje utvrđene konvencije koje nisu obavezujuće, ali koje svi korisnici i čitaoci vašeg koda očekuju da vide. Ne pokušavajte da nadmudrite druge, inače ćete nadmudriti sebe.
Napišite kompatibilan kod
Prije svega, mislim na standardnu biblioteku. Veoma je poželjno da se interfejsi vaših klasa i funkcija mogu koristiti sa standardnim i drugim bibliotekama (na primer, Boost).
Slobodno pogledajte STL i Boost interfejse. Uz rijetke izuzetke, tamo ćete vidjeti dostojan uzor.
Iskoristite sve alate otvorenog koda
Za istu statičku analizu, postoje najmanje dva otvorena besplatna alata koja se mogu povezati samo jednom na bilo koji projekat sa CMake build sistemom.
Na kraju, želim da naglasim da ne zagovaram da se ne koristi PVS ili bilo koji drugi statički analizator. Ali ohrabrujem vas da razmislite o tome kako se dogodilo da statički analizator stalno pronalazi značajne greške u vašem kodu.
Ovo je samo posledica. Moramo potražiti i ukloniti uzrok.