Videl sem publikacijo, ki se jo je PVS naučil analizirati pod Linuxom, in se odločil, da jo preizkusim na svojih projektih. In to je tisto, kar je nastalo iz tega.
Na žalost PVS včasih naredi sintaksne napake in ustvari lažno pozitivna sporočila, ko je koda popolnoma pravilna.
Na primer, obstaja funkcija, ki vrne 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 beseda auto Lahko pomeni void, za to je avto. Toda PVS je ustvaril naslednja sporočila:
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.
Zelo počasno spletno mesto
Da, v spletnem vmesniku je poleg vsakega sporočila povezava do ustreznega diagnostičnega opisa s primeri. Ko pa klikneš na povezavo, moraš čakati kar dolgo in včasih se tudi to zgodi 504 Gateway Time out.
Jezik
Vsi opisi so v ruščini, kar je super. Toda povezave iz poročila vedno vodijo do angleške različice. Lepo bi bilo, če bi lahko preklopili jezik, da bi si lahko diagnostiko takoj ogledali v ruščini. V vmesniku nisem našel takšne možnosti.
Neprijetno je delati z diagnostičnimi nivoji prek konzole
Začnimo z dejstvom, da sta dva uporabljena ukaza (ta pvs-studio-analyzer и plog-converter) različne oblike za določanje diagnostike.
Pomoč za pvs-studio-analyzer se 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
Dolgo sem poskušal ugotoviti, kam naj grem add (»dodajanje vrednosti«). Poskušal sem jih našteti ločene z vejicami:
pvs-studio-analyzer analyze ... -a 1,4,16
Večkrat sem poskušal registrirati ključ:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16
In šele takrat sem ugotovil, da so to bitne maske! In potrebujete povzetiIn ne add pomeni. Če želite na primer dobiti splošno diagnostiko, diagnostiko za mikrooptimizacije in MISRA, jih morate sešteti (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44
Uporaba bitnih mask v uporabniških vmesnikih je na splošno slaba oblika. Vse to bi bilo mogoče interno povzeti in za uporabnika nastaviti niz zastavic.
Poleg tega obstaja tudi pripomoček plog-converter, ki ustvari človeku berljive informacije statične analize. Ima druge težave.
Pomoč za program plog-converter poročila:
-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
Tu so se pojavile nekatere "nivoje", ki jih prej ni bilo, pa tudi v dokumentaciji nisem našel ničesar o njih.
Na splošno ni jasno. Zato sem vse postavil na maksimum.
Kup neumnih psovk na Catch
Dva od treh projektov, ki sem jih analiziral, uporabljata knjižnico za testiranje enot Catch2. In levji delež sporočil (!!! 90 od 138 v enem in 297 od 344 v drugem!!!) ima naslednjo obliko:
Ne upošteva večnitnosti
Obstaja veliko lažnih pozitivnih rezultatov o domnevno nespremenljivih spremenljivkah ali neskončnih zankah, medtem ko delo s temi spremenljivkami poteka iz različnih niti, in če temu ne bi bilo tako, potem testi enot ne bi delovali.
Vendar, ali lahko statični analizator to sploh upošteva? ne vem
PVS ni našel nobene prave napake v mojih odprtokodnih projektih Burst и Naslednji, pa tudi v delovnem osnutku, ki ga iz očitnih razlogov ne morem predstaviti. Res je, da je vredno upoštevati, da so bile nekatere pomanjkljivosti že ulovljene in popravljene pred uporabo Cppcheck и scan-build.
Na splošno je vtis vseh teh analizatorjev približno enak: da, ujamejo nekaj, včasih celo nekaj pomembnega, a na splošno je prevajalnik dovolj.
Možno je (in osebno rad tako mislim), da naša ekipa uporablja prakse razvoja programske opreme, ki nam omogočajo, da ustvarimo minimalno količino usrane kode. Bolje je ne ustvarjati težav, kot pa jih junaško premagati.
Zato si dovolim dati nekaj nasvetov, kako pisati v C++ tako, da nikomur ne odstrelimo nog ali udarimo z grabljami v čelo.
Izkoristite diagnostiko prevajalnika
Naša ekipa uporablja (in vam svetuje) naslednje možnosti zbiranja:
Omogočite jih v svojem projektu in se naučite veliko o svoji kodi.
Drži se standarda
Poskusite ne uporabljati stvari, ki so odvisne od platforme, če obstajajo standardni analogi, in če absolutno ne morete brez njih, jih zavijte v posebne bloke za makre (ali kaj drugega) in preprosto ne dovolite, da se vaša koda prevede pod nepodprtimi pogoji.
Držite se standardne operacijske semantike
Seštevanje mora biti seštevanje, množenje mora biti množenje, klic funkcije mora biti klic funkcije, kopiranje mora biti kopiranje, prenos mora biti prenos, vsebnik mora biti ponovljiv, iterator mora imeti napredovanje ++ in dereferenciranje *. In tako dalje in tako naprej.
Mislim, da je ideja jasna. Obstajajo uveljavljene konvencije, ki niso zavezujoče, vendar jih vsi uporabniki in bralci vaše kode pričakujejo. Ne poskušajte prelisičiti drugih, sicer boste prelisičili sebe.
Napišite združljivo kodo
Najprej mislim na standardno knjižnico. Zelo zaželeno je, da se lahko vmesniki vaših razredov in funkcij uporabljajo s standardnimi in drugimi knjižnicami (na primer Boost).
Vabimo vas, da si ogledate vmesnika STL in Boost. Z redkimi izjemami boste tam videli vrednega vzornika.
Kar najbolje izkoristite odprtokodna orodja
Za isto statično analizo obstajata vsaj dve odprti brezplačni orodji, ki ju je mogoče samo enkrat povezati s katerim koli projektom s sistemom gradnje CMake.
Nazadnje bi rad poudaril, da ne zagovarjam neuporabe PVS ali katerega koli drugega statičnega analizatorja. Vendar vas spodbujam, da razmislite o tem, kako se je zgodilo, da statični analizator nenehno najde pomembne napake v vaši kodi.
To je samo posledica. Poiskati in odpraviti moramo vzrok.