A análise estática melhorará a base de código de projetos complexos em C ++

Grandes projetos antigos

Gradualmente e discretamente, uma situação se desenvolve quando a complexidade de projetos sérios em C ++ se torna proibitiva. Infelizmente, agora um programador de C ++ não pode confiar apenas em seus próprios pontos fortes.

Em primeiro lugar, há tanto código que uma situação é impossível quando há pelo menos alguns programadores no projeto que conhecem todo o projeto. Por exemplo, o kernel do Linux 1.0.0 continha cerca de 176 mil linhas de código. Isso é muito, mas foi possível colocar uma máquina de café nas proximidades e, em algumas semanas, mais ou menos, observe todo o código e entenda os princípios gerais de sua operação. Se usarmos o kernel Linux 5.0.0, o tamanho da base de código já é de cerca de 26 milhões de linhas de código. O código do kernel cresceu quase 150 vezes. Você só pode selecionar várias partes do projeto e participar de seu desenvolvimento. É impossível sentar e descobrir exatamente como tudo isso funciona, quais são as relações entre as várias seções do código.

Em segundo lugar, a linguagem C ++ continua a evoluir rapidamente. Por um lado, isso é bom, pois existem construções que permitem escrever código mais compacto e seguro. Por outro lado, devido à compatibilidade com versões anteriores, os grandes projetos antigos se tornam heterogêneos. Eles entrelaçam abordagens antigas e novas para escrever código. A analogia com anéis em uma seção de uma árvore implora. Por isso, todos os anos, mergulhando em projetos escritos em C ++, está se tornando cada vez mais difícil. É necessário entender o código ao mesmo tempo, ambos escritos no estilo C com classes e em abordagens modernas (lambdas, semântica de movimento, etc.). Leva muito tempo para aprender C ++ completamente. Mas como ainda é necessário desenvolver projetos, as pessoas começam a escrever código em C ++ sem ter estudado todas as suas nuances até o fim. Isso leva a defeitos adicionais, mas é irracional por causa disso parar e aguardar que todos os desenvolvedores se familiarizem perfeitamente com o C ++.

A situação é desesperadora? Não. Uma nova classe de ferramentas vem ao resgate: analisadores de código estático. Muitos programadores experientes neste momento torceram os lábios, como se tivessem escorregado um limão :). Tipo, nós sabemos que esse é o seu interlocutor ... Há muitas mensagens, um pouco de senso ... Sim, e qual é essa nova classe de ferramentas ?! Nós lançamos o lançamento há 20 anos.

Não obstante, arrisco-me a afirmar que esta é precisamente uma nova classe de ferramentas. O que aconteceu de 10 a 20 anos atrás não é de todo as ferramentas que agora são chamadas de analisadores estáticos. Primeiro, não estou falando sobre ferramentas orientadas à formatação de código. Eles também se relacionam com ferramentas de análise estática, mas agora estamos falando sobre a identificação de erros no código. Em segundo lugar, as ferramentas modernas usam tecnologias sofisticadas de análise, levando em consideração as interconexões entre diferentes funções e, na verdade, executando virtualmente certas seções do código. Esses não são os mesmos linters de 20 anos baseados em expressões regulares. A propósito, um analisador estático normal não pode ser feito em expressões regulares. Para encontrar erros, são usadas tecnologias como análise de fluxo de dados, anotação automática de método, execução simbólica etc.

Estas não são palavras abstratas, mas a realidade que observo como um dos criadores da ferramenta PVS-Studio. Confira este artigo para ver por que os analisadores podem encontrar erros interessantes.

No entanto, é muito mais importante que os analisadores estáticos modernos tenham amplo conhecimento dos padrões de erro. Além disso, os analisadores sabem mais do que desenvolvedores profissionais. Tornou-se muito difícil levar em conta e lembrar todas as nuances ao escrever código. Por exemplo, a menos que você leia especificamente sobre isso em algum lugar, você nunca imaginará que as chamadas para a função memset para apagar dados privados às vezes desaparecem, pois, do ponto de vista do compilador, a chamada para a função memset é redundante. Enquanto isso, essa é uma falha grave de segurança CWE-14 , encontrada literalmente em todo lugar . Ou quem, por exemplo, sabe o que é perigoso nesse envase de recipiente?

std::vector<std::unique_ptr<MyType>> v; v.emplace_back(new MyType(123)); 

Eu acho que nem todos perceberão imediatamente que esse código é potencialmente perigoso e pode levar a vazamentos de memória.

Além do amplo conhecimento de padrões, os analisadores estáticos são infinitamente atentos e nunca se cansam. Por exemplo, ao contrário de uma pessoa, eles não têm preguiça de olhar para os arquivos de cabeçalho para garantir que isspace e sprintf sejam funções reais e não macros malucas que estragam tudo. Tais casos demonstram a essência da dificuldade de encontrar erros em grandes projetos: algo muda em um lugar, mas quebra em outro.

Estou convencido de que em breve a análise estática se tornará parte integrante do DevOps - será tão natural e necessária quanto o uso do sistema de controle de versão. Isso já está acontecendo gradualmente em conferências dedicadas ao processo de desenvolvimento, onde a análise estática é cada vez mais mencionada como uma das primeiras linhas de defesa para combater bugs.

A análise estática serve como uma espécie de filtro grosso. É ineficiente procurar erros estúpidos e erros de digitação usando testes de unidade ou testes manuais. É muito mais rápido e mais barato corrigi-los imediatamente após escrever o código, usando análise estática para detectar problemas. Essa ideia, assim como a importância do uso regular do analisador, está bem descrita no artigo “ Incorpore a análise estática ao processo e não procure bugs nela ”.

Alguém pode dizer que não há sentido em ferramentas especiais, pois o compilador também aprende a fazer essas verificações estáticas. É sim. No entanto, os analisadores estáticos naturalmente não param e como as ferramentas especializadas superam os compiladores. Por exemplo, cada vez que verificamos o LLVM, encontramos erros usando o PVS-Studio.

O mundo oferece um grande número de ferramentas para análise de código estático. Como se costuma dizer, escolha ao seu gosto. Deseja encontrar muitos erros e vulnerabilidades em potencial, mesmo na fase de escrever código? Use analisadores de código estático e melhore a qualidade da sua base de código!



Se você deseja compartilhar este artigo com um público que fala inglês, use este link: Andrey Karpov. Por que a análise estática pode melhorar uma base de código C ++ complexa

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


All Articles