Jeg så en publikasjon som PVS hadde lært å analysere under Linux, og bestemte meg for å prøve den på mine egne prosjekter. Og det er dette som kom ut av det.
All dokumentasjon er på nettsiden deres, jeg kan bare si at hvis prosjektet ditt er bygget ved hjelp av CMake, så er alt veldig enkelt.
Gode diagnostiske beskrivelser
Hvis du genererer utgang i modus fullhtml, så har hver melding en lenke til en diagnostisk beskrivelse, med forklaringer, kodeeksempler og tilleggslenker.
Dessverre gjør PVS noen ganger syntaksfeil og genererer falske positive meldinger når koden er helt korrekt.
For eksempel er det en funksjon som returnerer 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));
}
Ja er stikkordet auto Kan bety void, det er det den er til auto. Men PVS produserte følgende meldinger:
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.
Veldig treg side
Ja, i nettgrensesnittet ved siden av hver melding er det en lenke til den tilhørende diagnosebeskrivelsen med eksempler. Men når du klikker på en lenke, må du vente ganske lenge, og noen ganger skjer det 504 Gateway Time-out.
Språk
Alle beskrivelser er på russisk, noe som er flott. Men lenker fra rapporten fører alltid til den engelske versjonen. Det ville vært fint å kunne bytte språk slik at du umiddelbart kan se diagnostikk på russisk. Jeg fant ikke et slikt alternativ i grensesnittet.
Det er upraktisk å jobbe med diagnostiske nivåer via konsollen
La oss starte med det faktum at de to kommandoene som ble brukt (dette pvs-studio-analyzer и plog-converter) forskjellige formater for å spesifisere diagnostikk.
Hjelp til pvs-studio-analyzer lyder:
-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
Jeg brukte lang tid på å finne ut hvor jeg skulle gå legge («legge til verdiene»)-tastene. Jeg prøvde å liste dem atskilt med komma:
pvs-studio-analyzer analyze ... -a 1,4,16
Jeg prøvde å registrere nøkkelen flere ganger:
pvs-studio-analyzer analyze ... -a 1 -a 4 -a 16
Og først da skjønte jeg at dette var bitmasker! Og du trenger oppsummereOg ikke legge betydninger. For eksempel, for å få generell diagnostikk, diagnostikk for mikrooptimaliseringer og MISRA, må du summere dem opp (4 + 8 + 32 = 44):
pvs-studio-analyzer analyze ... -a 44
Å bruke bitmasker i brukergrensesnitt er generelt dårlig. Alt dette kunne oppsummeres internt, og et sett med flagg kunne settes for brukeren.
I tillegg er det også et verktøy plog-converter, som genererer statisk analyseinformasjon som kan leses av mennesker. Hun har andre problemer.
Hjelp til programmet plog-converter rapporterer:
-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
Noen "nivåer" dukket opp her som ikke var der før, og jeg fant heller ikke noe om dem i dokumentasjonen.
Generelt er det ikke klart. Derfor setter jeg alt til det maksimale.
En haug med dumme banninger på Catch
To av de tre prosjektene jeg analyserte bruker et enhetstestingsbibliotek Catch2. Og brorparten av meldingene (!!! 90 av 138 i den ene og 297 av 344 i den andre!!!) har følgende form:
Tar ikke hensyn til multithreading
Det er mange falske positiver om antatt uforanderlige variabler eller endeløse løkker, mens arbeid med disse variablene skjer fra forskjellige tråder, og hvis dette ikke var slik, ville enhetstester ikke fungert.
Men kan en statisk analysator i det hele tatt ta hensyn til dette? Vet ikke.
PVS fant ingen reelle feil i open source-prosjektene mine Burst и Neste, samt i et arbeidsutkast, som jeg av åpenbare grunner ikke kan presentere. Riktignok er det verdt å huske på at noen mangler allerede er fanget og korrigert tidligere ved bruk Cppsjekk и scan-build.
Generelt er inntrykket fra alle disse analysatorene omtrent det samme: ja, de fanger opp noe, noen ganger til og med noe viktig, men totalt sett er kompilatoren nok.
Det er mulig (og jeg personlig liker å tro det) at teamet vårt bruker programvareutviklingspraksis som lar oss generere en minimumsmengde elendig kode. Det er bedre å ikke skape problemer enn å heroisk overvinne dem.
Derfor tar jeg meg friheten til å gi noen råd om hvordan man skriver i C++ på en slik måte at man ikke skyter bena av noen eller slår noen i pannen med en rake.
Få mest mulig ut av kompilatordiagnostikk
Teamet vårt bruker (og råder deg til) følgende kompileringsalternativer:
Aktiver dem i prosjektet ditt og lær mye om koden din.
Hold deg til standarden
Prøv å ikke bruke plattformavhengige ting hvis det er standardanaloger, og hvis du absolutt ikke kan klare deg uten dem, pakk dem inn i spesielle blokker for makroer (eller noe annet) og ikke la koden din kompileres under forhold som ikke støttes.
Hold deg til standard operasjonssemantikk
Addisjon må være addisjon, multiplikasjon må være multiplikasjon, funksjonsanrop må være funksjonskall, kopi må være kopi, bære må være bære, container må være itererbar, iterator må ha promotering ++ og dereferering *. Og så videre.
Jeg tror tanken er klar. Det er etablerte konvensjoner som ikke er bindende, men som alle brukere og lesere av koden din forventer å se. Ikke prøv å overliste andre, ellers vil du overliste deg selv.
Skriv kompatibel kode
Først og fremst mener jeg standardbiblioteket. Det er svært ønskelig at grensesnittene til klassene og funksjonene dine kan brukes med standardbiblioteker og andre biblioteker (for eksempel Boost).
Ta gjerne en titt på STL- og Boost-grensesnittene. Med sjeldne unntak vil du se et verdig forbilde der.
Få mest mulig ut av åpen kildekode-verktøy
For den samme statiske analysen er det minst to åpne gratisverktøy som kan kobles bare én gang til et hvilket som helst prosjekt med CMake-byggesystemet.
Til slutt vil jeg understreke at jeg ikke tar til orde for å ikke bruke PVS eller andre statiske analysatorer. Men jeg oppfordrer deg til å tenke på hvordan det skjedde at den statiske analysatoren hele tiden finner betydelige feil i koden din.
Dette er bare en konsekvens. Vi må lete etter og eliminere årsaken.