1 pontos por GN⁺ 2024-03-01 | 1 comentários | Compartilhar no WhatsApp

O que fazer se você herdou uma base de código C++ existente?

  • Ao começar em um novo emprego, mudar de equipe ou depois que um colega experiente sai, você acaba responsável por uma grande base de código C++ com estrutura complexa e peculiar.
  • É preciso corrigir bugs e adicionar novos recursos, mas não dá para ignorar nem simplesmente eliminar a base de código. Ela é importante para quem paga seu salário, então também é importante para você.

Primeiro passo: fazer o código funcionar localmente

  • Faça apenas as mudanças mínimas no código e no sistema de build para colocá-lo para funcionar localmente. Ainda não faça uma grande refatoração.

Remover o que é desnecessário

  • Remova tudo que não seja absolutamente necessário para fornecer os recursos que a empresa ou o projeto de código aberto anuncia e vende.

Trazer o projeto para o século 21

  • Adicione CI (integração contínua), linter, fuzzing, formatação automática etc.

Melhorar o código gradualmente

  • Faça mudanças pequenas e graduais no código. Repita isso de forma iterativa até levar o projeto a um estado aceitável em termos de segurança da aplicação, experiência do desenvolvedor, correção e desempenho.

Considerar reescrever partes em uma linguagem com segurança de memória

  • Se possível, considere reescrever parte do código em uma linguagem com segurança de memória.

Especificar as plataformas suportadas

  • Documente no README os pares <arquitetura>-<sistema operacional> oficialmente suportados. Por exemplo, x86_64-linux ou aarch64-darwin.

Fazer a build funcionar nas máquinas

  • Garanta que seja possível compilar de forma confiável e consistente em todas as plataformas suportadas.

Fazer os testes passarem nas máquinas

  • Se não houver testes, escreva testes antes de alterar o código e volte depois disso.

Descrever no README como compilar e testar a aplicação

  • Simplifique os comandos de build e teste para que até pessoas não especialistas consigam seguir com facilidade.

Procurar ganhos rápidos para acelerar build e testes

  • Procure maneiras simples de acelerar build e testes sem alterar o sistema de build.

Remover código desnecessário

  • Use avisos do compilador e o linter para encontrar e remover código não utilizado.

Linter

  • Não fique obcecado com regras de linter; adicione algumas regras básicas e integre-as ao ciclo de desenvolvimento.

Formatação de código

  • Em um momento apropriado, aplique em lote um estilo de código a toda a base e faça commit da configuração.

Sanitizers

  • Use sanitizers para detectar e corrigir bugs reais e vazamentos de memória.

Adicionar um pipeline de CI

  • Automatize todos os aspectos positivos já configurados (linter, formatação de código, testes etc.) e gere binários para produção em todas as mudanças.

Melhorar o código gradualmente

  • Foque em objetivos concretos como segurança, correção e desempenho, evitando critérios subjetivos como “código limpo”.

Reescrever em uma linguagem com segurança de memória?

  • Isso é um trabalho em andamento e envolve muitos cuidados. Faça isso apenas quando houver uma razão clara.

Conclusão

  • O texto oferece um plano concreto e passo a passo para sair de uma base de código C++ legada e complexa.

Apêndice: gerenciamento de dependências

  • Em C++, não existe gerenciamento de dependências, e a maioria usa gerenciadores de pacotes do sistema. No entanto, isso não é uma boa ideia.
  • A opinião do autor sobre gerenciamento de dependências é usar submódulos git e compilar a partir do código-fonte.

Opinião do GN⁺

  • Este artigo oferece um guia prático, passo a passo, útil para engenheiros de software iniciantes que herdaram uma base de código C++.
  • Lidar com código legado é um desafio comum para muitos desenvolvedores, e este artigo oferece conselhos práticos para esse tipo de situação.
  • Destacar a importância dos testes durante o processo de melhoria da base de código reflete boas práticas de desenvolvimento de software.
  • A opinião do autor sobre gerenciamento de dependências é controversa, e em projetos reais muitas vezes gerenciadores de pacotes modernos como Conan ou vcpkg são usados com sucesso.
  • Ao adotar tecnologias, é preciso considerar as características do projeto e o nível técnico da equipe, e este artigo pode ser um bom ponto de partida para ajudar nessas decisões.

1 comentários

 
GN⁺ 2024-03-01
Comentários do Hacker News
  • Em alguns comentários do Hacker News, foram apresentadas recomendações para quando se herda um projeto em C++:

    • Builds reproduzíveis: recomenda-se encapsular o ambiente de build com ferramentas como Docker para tornar ferramentas e dependências claras e reproduzíveis.
    • Build limpo com a opção -Wall: corrigir os avisos para resolver problemas no código e, em casos raros, ignorar avisos somente depois de entendê-los.
    • Sugere-se fazer testes iniciais com ferramentas como Valgrind para investigar erros de leitura/escrita.
    • Recomenda-se manter o refactoring, no início, em um escopo localizado e evitar grandes reformulações antes de entender a estrutura geral.
  • Outros comentários defendem que é importante introduzir primeiro CI, linting, auto-formatting etc.:

    • Antes de remover partes desnecessárias do código, é preciso entender como o programa funciona, e ferramentas de análise estática podem oferecer insights sobre onde o programa precisa de trabalho.
  • Um usuário sugeriu mudar para uma nova equipe ou empresa.

  • Há também comentários mencionando a importância de ferramentas e técnicas para entender o código:

    • É importante usar ferramentas para indexar o codebase, criar diagramas de sequência UML e fazer anotações como se estivesse ensinando outra pessoa.
  • Um comentário oferece conselhos sobre adicionar CI, linters, fuzzing e auto-formatting para modernizar o projeto:

    • Com CI, garante-se que o projeto possa ser compilado também em outros ambientes, e usa-se warnings do compilador e analisadores estáticos para identificar problemas no código.
    • Configurar testes unitários para partes importantes do código ajuda a verificar se ele está fazendo o trabalho correto.
    • A formatação automática tem prioridade menor, e recomenda-se seguir o estilo do mantenedor original.
  • Outro comentário critica o conselho de reescrever partes em uma linguagem com segurança de memória:

    • É difícil garantir os recursos necessários para o trabalho adicional, é preciso conhecimento de outra linguagem além de C++, e os testes podem ficar mais complexos.
  • Há ainda um comentário defendendo que usar git submodules e compilação a partir do código-fonte é superior a usar um gerenciador de pacotes:

    • Aponta-se que é estranho fazer esse tipo de crítica antes de experimentar ferramentas como o vcpkg.

Esses comentários apresentam diferentes abordagens e conselhos para quando se herda um projeto em C++, mostrando opiniões variadas sobre gerenciamento de projeto, entendimento do código, refactoring e estratégias de modernização.