Revisão independente do PVS-Studio (Linux, C ++)

Vi a publicação que o PVS aprendeu a analisar no Linux e decidi experimentar seus projetos. E foi isso que aconteceu.



Conteúdo


  1. Prós
  2. Contras
  3. Sumário
  4. Posfácio


Prós


Suporte responsivo


Solicitei uma chave de avaliação e eles a enviaram no mesmo dia.


Documentação clara o suficiente


Foi possível iniciar o analisador sem problemas. A ajuda para comandos do console também está disponível (embora haja reclamações, consulte a seção Contras ).


Capacidade de análise multithread


O analisador possui uma opção "padrão" -j , que permite analisar em paralelo em várias tarefas. Isso economiza muito tempo.


Boa visualização


Muitos formatos de saída diferentes, de texto a um pequeno focinho da web. A face da Web é conveniente, concisa, com dicas próximas às linhas do código e links para descrições de diagnósticos .


Fácil integração de montagem


Toda a documentação está no site deles, só posso dizer que, se o seu projeto for construído usando o CMake, tudo será muito simples.


Boas descrições de diagnóstico


Se você gerar saída no modo fullhtml , cada mensagem fullhtml um link para uma descrição do diagnóstico, com explicações, exemplos de código e links adicionais.



Contras


Ignorância do Analisador de Linguagem C ++


Infelizmente, o PVS às vezes erra na sintaxe e gera mensagens falsas positivas com o código perfeitamente correto.


Por exemplo, há uma função que retorna 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)); } 

Sim, a palavra auto chave auto pode significar void , por isso é automático . Mas o PVS emitiu estas mensagens:


 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. 

Site muito lento


Sim, no focinho da web ao lado de cada mensagem, há um link para a descrição correspondente do diagnóstico com exemplos. Mas quando você clica no link, precisa aguardar o tempo suficiente e, às vezes, ocorre 504 Tempo limite do gateway .


Linguagem


Todas as descrições estão em russo, isso é ótimo. Mas os links do relatório sempre levam à versão em inglês. Seria bom poder alternar o idioma para que você possa visualizar o diagnóstico imediatamente em russo. Não encontrei essa oportunidade na interface.


Inconveniente trabalhar com níveis de diagnóstico por meio do console


Para começar, os dois comandos usados ​​( pvs-studio-analyzer e plog-converter ) têm diferentes formatos de trabalho de diagnóstico.


A ajuda para o pvs-studio-analyzer diz:


 -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 

Durante muito tempo, tentei entender onde adicionar ("adicionar os valores") chaves. Tentou listar com uma vírgula:


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

Tentei registrar a chave várias vezes:


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

E só então eu percebi que estas são máscaras! E você precisa resumir , não adicionar valores. Por exemplo, para obter diagnósticos gerais, diagnósticos para microoptimizações e MISRA, é necessário somar (4 + 8 + 32 = 44):


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

Usar máscaras de bits nas interfaces do usuário geralmente é uma má ideia. Tudo isso pode ser resumido por dentro, e o usuário define um conjunto de sinalizadores.


Além disso, há também o utilitário plog-converter , que gera informações legíveis por humanos sobre a análise estática. Ela tem outros problemas.


Ajuda para os relatórios do programa plog-converter :


 -a, --analyzer Specifies analyzer(s) and level(s) to be used for filtering, ie 'GA:1,2;64:1;OP:1,2,3;CS:1;MISRA:1,2' Default: GA:1,2 

Algum tipo de "níveis" apareceu aqui, o que nunca havia sido visto antes, e eu também não encontrei nada sobre eles na documentação.


Em geral, não está claro. Portanto, defino tudo ao máximo.


Um monte de palavrões estúpidos em Catch


Dois dos três projetos que analisei usam a biblioteca de testes de unidade Catch2 . E a maior parte das mensagens (!!! 90 de 138 em uma e 297 de 344 em outra !!!) têm a seguinte forma:


Catch2


Não considera multithreading


Existem muitos falsos positivos sobre variáveis ​​supostamente imutáveis ​​ou loops infinitos, enquanto o trabalho com essas variáveis ​​vem de threads diferentes e, se não fosse assim, os testes de unidade não funcionariam.


Multithreading


No entanto, um analisador estático pode levar isso em consideração? Eu não sei



Sumário


O PVS não encontrou nenhum erro real nos meus projetos abertos Burst e Proxima , bem como em um rascunho de trabalho, que eu, por razões óbvias, não posso apresentar. No entanto, deve-se ter em mente que algumas falhas já foram detectadas e corrigidas anteriormente usando Cppcheck e scan-build .


Em geral, a impressão de todos esses analisadores é a mesma: sim, eles capturam algo, às vezes até algo importante, mas no geral o compilador é suficiente.


É possível (e pessoalmente tenho o prazer de pensar que sim) que nossa equipe use essas práticas de desenvolvimento de software que nos permitem gerar a quantidade mínima de merda. Melhor não criar problemas do que superá-los heroicamente.


Portanto, tomo a liberdade de dar alguns conselhos sobre como escrever em C ++ de forma a não atirar nas pernas de ninguém e não raspar a testa.


Use o diagnóstico do compilador ao máximo


Nossa equipe usa (e aconselha) as seguintes opções de compilação:


 -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 

Inclua-os em seu projeto, aprenda muito sobre seu código.


Atenha-se ao padrão


Tente não usar coisas que dependem da plataforma se houver análogos padrão e, se você não puder ficar sem eles, envolva-os em blocos especiais para macros (ou de alguma forma) e não deixe que compilemos seu código em condições não suportadas.


Atenha-se à semântica de operação padrão


A adição deve ser adição, multiplicação por multiplicação, chamada de função por chamada de função, cópia deve copiar, transferência deve ser transferida, o contêiner deve ser iterável, o iterador deve ter ++ e promoção e desreferência * . E assim por diante e assim por diante.


Eu acho que a ideia é clara. Existem acordos estabelecidos que não são vinculativos, mas que todos os usuários e leitores do seu código esperam ver. Não tente enganar os outros, ou seja mais esperto que você.


Escreva código compatível


Antes de tudo, quero dizer a biblioteca padrão. É altamente desejável que as interfaces de suas classes e funções possam ser usadas com bibliotecas padrão e outras (por exemplo, Busto).


Fique à vontade para espiar as interfaces STL e Boost. Com raras exceções, você verá um modelo digno lá.


Aproveite ao máximo as ferramentas abertas


Para a mesma análise estática, há pelo menos duas ferramentas livres abertas conectadas a qualquer projeto com o sistema de criação do CMake à custa do "tempo".


Você pode ler mais sobre isso na minha publicação recente .



Posfácio


Concluindo, enfatizo que não desejo não usar o PVS ou qualquer outro analisador estático. Mas peço que você pense como o analisador estático encontra constantemente erros significativos no seu código.


Isso é apenas uma consequência. É necessário procurar e eliminar a causa.

Source: https://habr.com/ru/post/pt463027/


All Articles