Introdução: por que code review em C++ não é para os fracos
\n\nC++ é uma linguagem que dá ao programador um poder incrível. Mas, como dizia o tio Ben do "Homem-Aranha": "Com grandes poderes vêm grandes responsabilidades". E se em Python você pode acidentalmente misturar int e str e obter apenas uma exceção, em C++ o mesmo descuido pode levar a um comportamento indefinido (UB), que se manifestará um mês depois no servidor do cliente às 3 da manhã.
Code review em C++ não é uma mera formalidade no Jira. É o seu escudo contra segmentation fault, vazamentos de memória e código lento como uma lesma. Muitos desenvolvedores (especialmente aqueles vindos de Java ou Python) pensam que code review é verificar estilo e nomes de variáveis. Em C++, é mais profundo. Aqui, é preciso olhar a própria alma do programa: gerenciamento de memória, RAII, const-correctness e se aquele ponteiro inteligente não vai acertar o seu pé.
\n\nNeste artigo, reuni um checklist real para verificação de código C++. Use-o como referência quando fizer seu próximo code review. Vamos nessa!
\n\n1. Vazamentos de memória e gerenciamento de recursos (RAII)
\n\nEste é o ponto central do C++. Se você vir new sem delete — é uma bandeira vermelha. Mas no C++ moderno (C++11 em diante), não devemos escrever new manualmente. Use ponteiros inteligentes: std::unique_ptr, std::shared_ptr. Se o desenvolvedor usa ponteiros brutos (int*) para posse de recurso — é motivo para questionar.
Exemplo de código ruim (bandeira vermelha):
\n\nvoid process() {\n int* data = new int[1000];\n // ... algum código ...\n if (error) {\n return; // VAZAMENTO! delete não foi chamado\n }\n delete[] data;\n}\n\n\nExemplo de código bom (RAII):
\n\nvoid process() {\n std::vector<int> data(1000);\n // ... código ...\n if (error) {\n return; // Tudo ok, o vetor limpará a memória sozinho\n }\n}\n\n\nO que verificar no code review em C++:
\n- \n
- Há
new/deleteno código? Se sim — por quê? Por que nãostd::make_unique? \n std::unique_ptrestá sendo usado para posse exclusiva? \n std::shared_ptrnão está sendo passado por valor onde uma referência bastaria (é caro devido ao contador atômico)? \n - Há vazamentos em caso de exceções (exception safety)? \n
2. Comportamento indefinido (Undefined Behavior)
\n\nEm C++, o compilador confia no programador. Se você escreveu algo sem sentido, o compilador não vai te repreender — ele simplesmente gerará código que pode fazer qualquer coisa. UB é o flagelo do C++. Aqui está o que pegar na revisão:
\n\n- \n
- Acesso fora dos limites do array:
arr[10]para um array de 10 elementos. \n - Uso de variável após movimentação:
std::movenão é mágica, o objeto após a movimentação está em um estado válido, mas indefinido. \n - Estouro de inteiro com sinal:
INT_MAX + 1é UB! (Ao contrário do Java, onde é apenas um wrap). \n - Referência pendente (dangling reference): retornar referência a uma variável local. \n
Exemplo de UB (procure isso no code review):
\n\nint& getValue() {\n int x = 42;\n return x; // UB! x é destruído após sair da função\n}\n\nvoid example() {\n int& ref = getValue();\n std::cout << ref; // Pode imprimir 42, ou lixo, ou crashar\n}\n\n\nDica para o revisor: se vir aritmética com int, especialmente em loops ou ao trabalhar com tamanhos — verifique se não haverá estouro. É melhor usar size_t para índices e std::ssize() para comparação segura.