Dann Luciano

A lifelong student of the art of programming computers!

Safe C++

| Comments

Recentemente terminei de ler o livro Safe C++: How to Avoid Common Mistakes do Vladimir Kushnir e publicado pela O’Reilly. Recomendo a leitura do livro, pois alguns erros bobos que cometemos no dia-a-dia são facilmente solucionados com soluções simples (minhas preferidas). Uma das frases que mais gostei do autor foi a de que os compiladores são nossos amigos e não o contrario (o clang então). Vou traduzir a estrutura do livro e expor as recomendações do autor.

O repositório com códigos com as dicas do livro estão no Github do Vladimir

Parte I. Estrategia de Caça aos Bugs para C++

  • Capitulo 01: De Onde Vem os Bugs em C++

  • Capitulo 02: Como Capiturar um Bug

    Para diagnostico de erros em tempo de compilação:

    • Use explict antes de construtores com um único argumento. Isto evita conversões não desejadas dos operandos.
    • Use classes diferentes para representar diferentes tipos de dados.
    • Use enums para criar novos tipos de dados e não constantes inteiras.

Parte II. Caça aos Bugs: Um bug de cada vez

  • Capitulo 03: O Que Fazer Quando Encontrar um Erro em Tempo de Execução

  • Capitulo 04: Índice Fora dos Limites

    Para evitar erros de “index out of bounds”:

    • Não use arrays alocados staticamente ou dinamicamente. Use os templates da STL vector ou array.
    • Não use os operadores new[] ou delete[]. Use os conteiner vector para alocar multiplos elementos.
    • Use scpp::array ou scpp::vector, pois eles possuem algumas verificações interessantes (sanity checks).
  • Capitulo 05: Aritmética de Ponteiros

    Evite aritmética de ponteiros. Use os templates vector ou array com os índices.

  • Capitulo 06: Ponteiros, Referencias ou Iteradores Inválidos

    Para evitar erros com ponteiros, referencias ou iteradores inválidos:

    • Não use ponteiros, referencias ou iteradores depois de modificar um conteiner.
  • Capitulo 07: Variáveis Não Inicializadas

    Para evitar erros de variáveis não inicializadas especialmente membros de classes:

    • Não use os tipos primitivos como int, unsigned, double, bool em membros de classes. Em vez disso use Int, Unsigned, Double, Bool, porque você não vai precisar inicializalos. (Eu particularmente ainda acredito que isso deixa nosso código mais orientado a objeto).
    • Use as novas classes em vez dos tipos primitivos na passagem de parâmetros para funções ou métodos para conseguir adicionalmente tipos corretos.
  • Capitulo 08: Perdas de Memórias

    Para evitar vazamentos de memória:

    • Toda vez que criar um objeto usando o operador new, imediatamente atribua o resultado a um smart pointer (reference counting ou scoped).
    • Use o operador new sempre sem os colchetes([]). Se precisar criar um array, crie um novo template vector, que é um único objeto.
  • Capitulo 09: Des-referenciando um Ponteiro Nulo

    Para capturar tentativas de des-referenciar um ponteiro nulo:

    • Se você tiver um ponteiro que é proprietário do objeto que ele aponta, use um smart pointer (reference counting ou scoped)
    • Quando você tiver um ponteiro puro(raw) T* apontando para um objeto que não o pertence, use o template Ptr<T>.
    • Para ponteiros constantes (const T*) use Ptr<const T>.
  • Capitulo 10: Construtores de Copia e Operadores de Atribuição

    Para evitar erros nos construtores de copia e operadores de atribuição:

    • Quando possível, evite escrever o construtor de copia e o operador de atribuição para sua classe.
    • Se a versão padrão não funcionar para você considere proibir a copia das instancias da sua classe declarando o construtor de copia e operador de atribuição como privado.
  • Capitulo 11: Evite Escrever Código nos Destrutores

    Para evitar perdas de memórias quando uma exceções forem lançadas dentro do construtor:

    • Desenhe sua classe de um modo que os destrutores sejam vazios.
  • Capitulo 12: Como Escrever Operadores de Comparação Consistentes

    Para evitar erros quando escrever operadores de comparação:

    • Escreva uma função CompareTo() e use a macro SCPP_DEFINE_COMPASION_OPERATORS para implementar todos os operadores de comparação.
  • Capitulo 13: Erros Quando se Usa a Biblioteca Padrão do C

    Para evitar vazamentos de buffers e crashes quando usar funcões da Biblioteca Padrão C evite usar a biblioteca padrão de strings (string.h):

    • Alem de não serem seguras e em alguns momentos mais lentas que as classes correspondentes em C++, como a std::string e std::ostringstream.

    • Use as classes do C++ e você evitar um numero possíveis erros como comportamentos não esperados.

Parte III. A Alegria de Caça aos Bugs: a Partir de Testes de Depuração para Produção

  • Capitulo 14: Princípios Gerais de Teste

  • Capitulo 15: Estratégia de Debug nos Erros

  • Capitulo 16: Faça Seu Código Facilmente “Debugavel”

  • Capitulo 17: Conclusões

Comments