Sendependa revizio de PVS-Studio (Linukso, C++)

Mi vidis publikaĵon, kiun PVS lernis analizi sub Linukso, kaj decidis provi ĝin en miaj propraj projektoj. Kaj jen kio el ĝi eliris.


Enhavo

  1. Puloj
  2. Miksoj
  3. Rezultoj
  4. Antaŭparolo

Puloj

Respondema subteno

Mi petis provan ŝlosilon kaj ili sendis ĝin al mi la saman tagon.

Sufiĉe klara dokumentado

Ni sukcesis lanĉi la analizilon senprobleme. Helpo por konzolaj komandoj ankaŭ haveblas (kvankam estas iuj plendoj ĉi tie, vidu sekcion Miksoj).

Eblo de multfadena analizo

La analizilo havas "norman" opcion -j, permesante analizon paralele en pluraj taskoj. Ĉi tio ŝparas multan tempon.

Bona bildigo

Multaj malsamaj eligformatoj, de teksto ĝis malgranda retmuzelo. La retinterfaco estas oportuna, konciza, kun sugestoj apud linioj en la kodo kaj ligiloj al diagnozaj priskriboj.

Facila integriĝo en la asembleon

La tuta dokumentaro estas en ilia retejo, mi nur povas diri, ke se via projekto estas konstruita per CMake, tiam ĉio estas tre simpla.

Bonaj diagnozaj priskriboj

Se vi generas eligon en reĝimo fullhtml, tiam ĉiu mesaĝo havas ligilon al diagnoza priskribo, kun klarigoj, kodekzemploj kaj aldonaj ligiloj.

Miksoj

Nescio pri la C++-lingvo fare de la analizilo

Bedaŭrinde, PVS foje faras sintaksajn erarojn kaj generas falsajn pozitivajn mesaĝojn kiam la kodo estas tute ĝusta.

Ekzemple, estas funkcio kiu revenas 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));
}

Jes estas la ŝlosila vorto auto Povas signifi void, por tio ĝi estas aŭto. Sed PVS produktis la sekvajn mesaĝojn:

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.

Tre malrapida retejo

Jes, en la retinterfaco apud ĉiu mesaĝo estas ligilo al la responda diagnoza priskribo kun ekzemploj. Sed kiam vi alklakas ligilon, vi devas atendi sufiĉe longe, kaj foje ĝi okazas 504 Enirejo Tempo-eksperto.

Lingvo

Ĉiuj priskriboj estas en la rusa, kio estas bonega. Sed ligiloj de la raporto ĉiam kondukas al la angla versio. Estus bone povi ŝanĝi la lingvon, por ke vi povu tuj vidi diagnozojn en la rusa. Mi ne trovis tian opcion en la interfaco.

Estas maloportune labori kun diagnozaj niveloj per la konzolo

Ni komencu per la fakto, ke la du komandoj uzataj (ĉi tio pvs-studio-analyzer и plog-converter) malsamaj formatoj por specifi diagnozon.

Helpo por pvs-studio-analyzer legas:

-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

Mi pasigis longan tempon provante eltrovi kien iri aldoni ("aldonante la valorojn") klavoj. Mi provis listigi ilin apartigitaj per komoj:

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

Mi provis registri la ŝlosilon plurajn fojojn:

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

Kaj nur tiam mi rimarkis, ke ĉi tiuj estas mordaj maskoj! Kaj vi bezonas resumikaj ne aldoni signifoj. Ekzemple, por akiri ĝeneralajn diagnozojn, diagnozojn por mikro-optimumigoj kaj MISRA, vi devas resumi ilin (4 + 8 + 32 = 44):

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

Uzi bitmaskojn en uzantinterfacoj estas ĝenerale malbona formo. Ĉio ĉi povus esti resumita interne, kaj aro da flagoj povus esti agordita por la uzanto.

Krome, ekzistas ankaŭ utileco plog-converter, kiu generas homlegeblajn senmovajn analizinformojn. Ŝi havas aliajn problemojn.

Helpo por la programo plog-converter raportoj:

-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

Kelkaj "niveloj" aperis ĉi tie, kiuj antaŭe ne estis tie, kaj mi trovis nenion pri ili ankaŭ en la dokumentaro.

Ĝenerale, ĝi ne estas klara. Tial mi starigis ĉion al la maksimumo.

Aro da stultaj blasfemoj sur Catch

Du el la tri projektoj kiujn mi analizis uzas unutestan bibliotekon Kapto2. Kaj la plej granda parto de mesaĝoj (!!! 90 el 138 en unu kaj 297 el 344 en la alia!!!) havas la jenan formon:

Sendependa revizio de PVS-Studio (Linukso, C++)

Ne konsideras multfadenadon

Estas multaj falsaj pozitivoj pri supozeble senŝanĝaj variabloj aŭ senfinaj bukloj, dum laboro kun ĉi tiuj variabloj okazas de malsamaj fadenoj, kaj se ĉi tio ne estus tiel, tiam unutestoj ne funkcius.

Sendependa revizio de PVS-Studio (Linukso, C++)

Tamen, ĉu statika analizilo eĉ povas konsideri tion? Ne scias.

Rezultoj

PVS ne trovis verajn erarojn en miaj malfermfontaj projektoj eksplodis и Proksima, same kiel en laborskizo, kiun, pro evidentaj kialoj, mi ne povas prezenti. Vere, indas memori, ke iuj mankoj jam estis kaptitaj kaj korektitaj pli frue uzante Cppcheck и scan-build.

Ĝenerale, la impreso de ĉiuj ĉi analiziloj estas proksimume la sama: jes, ili kaptas ion, foje eĉ ion gravan, sed entute la kompililo sufiĉas.

Eblas (kaj mi persone ŝatas pensi tion) ke nia teamo uzas programojn pri disvolvado, kiuj ebligas al ni generi minimuman kvanton da aĉa kodo. Pli bone estas ne krei problemojn ol heroe venki ilin.

Sekve, mi prenas la liberon doni kelkajn konsilojn pri kiel skribi en C++ tiel, ke ne forpafu ies krurojn aŭ bati iun en la frunto per rastilo.

Utiligu la diagnozon de la kompililo

Nia teamo uzas (kaj konsilas vin) la jenajn kompilopciojn:

-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

Ebligu ilin en via projekto kaj lernu multon pri via kodo.

Restu al la normo

Provu ne uzi platform-dependajn aferojn se ekzistas normaj analogoj, kaj se vi absolute ne povas fari sen ili, envolvu ilin en specialajn blokojn por makrooj (aŭ io alia) kaj simple ne lasu vian kodon esti kompilita sub nesubtenataj kondiĉoj.

Restu al norma operacia semantiko

Aldono devas esti aldono, multipliko devas esti multipliko, funkciovoko devas esti funkciovoko, kopio devas esti kopio, porti devas esti porti, ujo devas esti itebla, iteratoro devas havi promocion ++ kaj dereferencing *. Kaj tiel plu kaj tiel plu.

Mi pensas, ke la ideo estas klara. Estas establitaj konvencioj kiuj ne estas devigaj, sed kiujn ĉiuj uzantoj kaj legantoj de via kodo atendas vidi. Ne provu superruzi aliajn, alie vi superruzos vin.

Skribu kongruan kodon

Antaŭ ĉio, mi celas la norman bibliotekon. Estas tre dezirinde, ke la interfacoj de viaj klasoj kaj funkcioj povas esti uzataj kun normaj kaj aliaj bibliotekoj (ekzemple, Boost).

Bonvolu rigardi la interfacojn STL kaj Boost. Kun maloftaj esceptoj, vi vidos tie indan rolmodelon.

Utiligu la ilojn de malferma fonto

Por la sama statika analizo, ekzistas almenaŭ du malfermitaj senpagaj iloj, kiuj povas esti konektitaj nur unufoje al iu ajn projekto kun la konstrua sistemo CMake.

Vi povas legi pli pri tio en mia lastatempa eldonaĵo.

Antaŭparolo

Fine, mi ŝatus emfazi, ke mi ne rekomendas ne uzi PVS aŭ ajnajn aliajn statikajn analizilojn. Sed mi kuraĝigas vin pensi pri kiel okazis, ke la senmova analizilo konstante trovas gravajn erarojn en via kodo.

Ĉi tio estas nur sekvo. Ni devas serĉi kaj forigi la kaŭzon.

fonto: www.habr.com

Aldoni komenton