Revisione indipendente di PVS-Studio (Linux, C++)

Ho visto una pubblicazione che PVS aveva imparato ad analizzare sotto Linux e ho deciso di provarla sui miei progetti. E questo è quello che ne è venuto fuori.


contenuto

  1. Pro
  2. Contro
  3. Risultati di
  4. postfazione

Pro

Supporto reattivo

Ho richiesto una chiave di prova e me l'hanno inviata lo stesso giorno.

Documentazione abbastanza chiara

Siamo riusciti ad avviare l'analizzatore senza problemi. È disponibile anche la guida per i comandi della console (sebbene ci siano alcune lamentele qui, vedere la sezione Contro).

Possibilità di analisi multi-thread

L'analizzatore ha un'opzione "standard". -j, consentendo di svolgere l'analisi in parallelo in diversi compiti. Ciò consente di risparmiare molto tempo.

Buona visualizzazione

Molti formati di output diversi, dal testo a una piccola museruola web. L'interfaccia web è comoda, concisa, con suggerimenti accanto alle righe del codice e collegamenti alle descrizioni diagnostiche.

Facile integrazione nell'assieme

Tutta la documentazione è sul loro sito, posso solo dire che se il tuo progetto è realizzato utilizzando CMake, allora tutto è molto semplice.

Buone descrizioni diagnostiche

Se generi output in modalità fullhtml, quindi ogni messaggio ha un collegamento a una descrizione diagnostica, con spiegazioni, esempi di codici e collegamenti aggiuntivi.

Contro

Ignoranza del linguaggio C++ da parte dell'analizzatore

Sfortunatamente, PVS a volte commette errori di sintassi e genera messaggi falsi positivi quando il codice è completamente corretto.

Ad esempio, c'è una funzione che restituisce 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));
}

Sì, parola chiave auto Può significare void, ecco a cosa serve auto. Ma PVS ha prodotto i seguenti messaggi:

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.

Sito molto lento

Sì, nell'interfaccia web accanto a ciascun messaggio è presente un collegamento alla corrispondente descrizione diagnostica con esempi. Ma quando si fa clic su un collegamento, è necessario attendere parecchio tempo e talvolta ciò accade Timeout gateway 504.

lingua

Tutte le descrizioni sono in russo, il che è fantastico. Ma i collegamenti del rapporto portano sempre alla versione inglese. Sarebbe bello poter cambiare la lingua in modo da poter visualizzare immediatamente la diagnostica in russo. Non ho trovato tale opzione nell'interfaccia.

È scomodo lavorare con i livelli diagnostici tramite la console

Partiamo dal fatto che i due comandi utilizzati (this pvs-studio-analyzer и plog-converter) formati diversi per specificare la diagnostica.

Aiuto per pvs-studio-analyzer si legge:

-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

Ho passato molto tempo cercando di capire dove andare aggiungere (“somma dei valori”). Ho provato ad elencarli separati da virgole:

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

Ho provato a registrare la chiave più volte:

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

E solo allora ho capito che si trattava di piccole maschere! E hai bisogno riassumereE non aggiungere significati. Ad esempio, per ottenere la diagnostica generale, la diagnostica per le micro-ottimizzazioni e MISRA, è necessario sommarle (4 + 8 + 32 = 44):

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

L'uso delle maschere di bit nelle interfacce utente è generalmente una cattiva forma. Tutto ciò potrebbe essere riepilogato internamente e una serie di flag potrebbe essere impostata per l'utente.

Inoltre, c'è anche un'utilità plog-converter, che genera informazioni di analisi statica leggibili dall'uomo. Ha altri problemi.

Aiuto per il programma plog-converter rapporti:

-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

Qui sono apparsi alcuni "livelli" che prima non c'erano e non ho trovato nulla nemmeno nella documentazione a riguardo.

In generale, non è chiaro. Ecco perché ho impostato tutto al massimo.

Un mucchio di stupide imprecazioni su Catch

Due dei tre progetti che ho analizzato utilizzano una libreria di unit test Catch2. E la maggior parte dei messaggi (!!! 90 su 138 in uno e 297 su 344 nell'altro!!!) hanno la seguente forma:

Revisione indipendente di PVS-Studio (Linux, C++)

Non tiene conto del multithreading

Esistono molti falsi positivi su variabili apparentemente immutabili o cicli infiniti, mentre il lavoro con queste variabili avviene da thread diversi e, se così non fosse, i test unitari non funzionerebbero.

Revisione indipendente di PVS-Studio (Linux, C++)

Tuttavia, un analizzatore statico può tenerne conto? Non lo so.

Risultati di

PVS non ha riscontrato alcun bug reale nei miei progetti open source scoppiare и Il prossimo, nonché in un progetto di lavoro che, per ovvi motivi, non posso presentare. È vero, vale la pena tenere presente che alcune carenze sono già state individuate e corrette in precedenza Cppcheck и scan-build.

In generale, l'impressione di tutti questi analizzatori è più o meno la stessa: sì, catturano qualcosa, a volte anche qualcosa di importante, ma nel complesso è sufficiente il compilatore.

È possibile (e personalmente mi piace pensarlo) che il nostro team utilizzi pratiche di sviluppo software che ci consentono di generare una quantità minima di codice di merda. È meglio non creare problemi che superarli eroicamente.

Mi permetto quindi di dare qualche consiglio su come scrivere in C++ in modo tale da non sparare alle gambe a nessuno o colpire qualcuno in fronte con un rastrello.

Ottieni il massimo dalla diagnostica del compilatore

Il nostro team utilizza (e ti consiglia di farlo) le seguenti opzioni di compilazione:

-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

Abilitali nel tuo progetto e impara molto sul tuo codice.

Attenersi allo standard

Cerca di non utilizzare cose dipendenti dalla piattaforma se ci sono analoghi standard e, se non puoi assolutamente farne a meno, avvolgili in blocchi speciali per macro (o qualcos'altro) e semplicemente non lasciare che il tuo codice venga compilato in condizioni non supportate.

Attenersi alla semantica operativa standard

L'addizione deve essere addizione, la moltiplicazione deve essere moltiplicazione, la chiamata di funzione deve essere chiamata di funzione, la copia deve essere copia, il riporto deve essere riporto, il contenitore deve essere iterabile, l'iteratore deve avere una promozione ++ e dereferenziazione *. E così via e così via.

Penso che l'idea sia chiara. Esistono convenzioni stabilite che non sono vincolanti, ma che tutti gli utenti e lettori del tuo codice si aspettano di vedere. Non cercare di superare in astuzia gli altri, altrimenti supererai te stesso.

Scrivi codice compatibile

Prima di tutto, intendo la libreria standard. È altamente auspicabile che le interfacce delle classi e delle funzioni possano essere utilizzate con librerie standard e di altro tipo (ad esempio Boost).

Sentiti libero di dare un'occhiata alle interfacce STL e Boost. Con rare eccezioni, lì vedrai un degno modello.

Ottieni il massimo dagli strumenti open source

Per la stessa analisi statica, ci sono almeno due strumenti gratuiti aperti che possono essere collegati una sola volta a qualsiasi progetto con il sistema di compilazione CMake.

Puoi leggere di più a riguardo nella mia recente pubblicazione.

postfazione

Infine, vorrei sottolineare che non sto consigliando di non utilizzare PVS o altri analizzatori statici. Ma ti incoraggio a pensare a come è successo che l'analizzatore statico trovi costantemente errori significativi nel tuo codice.

Questa è solo una conseguenza. Dobbiamo cercare ed eliminare la causa.

Fonte: habr.com

Aggiungi un commento