Introduction : pourquoi le code review en C++ n'est pas pour les âmes sensibles
\n\nC++ est un langage qui donne au programmeur une puissance incroyable. Mais, comme le disait oncle Ben dans « Spider-Man » : « Un grand pouvoir implique de grandes responsabilités ». Et si en Python vous pouvez accidentellement mélanger int et str et n'obtenir qu'une exception, en C++, la même maladresse peut conduire à un comportement indéfini (UB) qui se manifestera un mois plus tard sur le serveur du client à 3 heures du matin.
Le code review en C++ n'est pas une simple case à cocher dans Jira. C'est votre bouclier contre les segmentation fault, les fuites mémoire et un code lent comme une tortue. De nombreux développeurs (surtout ceux venant de Java ou Python) pensent que la revue de code consiste à vérifier le style et les noms de variables. En C++, c'est bien plus profond. Il faut regarder dans l'âme même du programme : la gestion de la mémoire, le RAII, la const-correctness et vérifier que ce pointeur intelligent ne va pas vous tirer dans le pied.
\n\nDans cet article, j'ai rassemblé une checklist réelle pour la vérification du code C++. Adoptez-la lorsque vous ferez votre prochain code review. C'est parti !
\n\n1. Fuites mémoire et gestion des ressources (RAII)
\n\nC'est le saint des saints du C++. Si vous voyez new sans delete — c'est un drapeau rouge. Mais en C++ moderne (C++11 et plus récent), nous ne devrions même pas écrire new manuellement. Utilisez les pointeurs intelligents : std::unique_ptr, std::shared_ptr. Si un développeur utilise des pointeurs bruts (int*) pour posséder une ressource — c'est une raison de poser une question.
Exemple de mauvais code (drapeau rouge) :
\n\nvoid process() {\n int* data = new int[1000];\n // ... du code ...\n if (error) {\n return; // FUITE ! delete n'est pas appelé\n }\n delete[] data;\n}\n\n\nExemple de bon code (RAII) :
\n\nvoid process() {\n std::vector<int> data(1000);\n // ... code ...\n if (error) {\n return; // Tout va bien, le vecteur nettoiera la mémoire lui-même\n }\n}\n\n\nQue vérifier lors d'un code review en C++ :
\n- \n
- Y a-t-il des
new/deletedans le code ? Si oui, pourquoi ? Pourquoi passtd::make_unique? \n std::unique_ptrest-il utilisé pour la possession exclusive ? \n std::shared_ptrn'est-il pas passé par valeur là où une référence suffirait (c'est coûteux à cause du compteur atomique) ? \n - Y a-t-il des fuites en cas d'exceptions (exception safety) ? \n
2. Comportement indéfini (Undefined Behavior)
\n\nEn C++, le compilateur fait confiance au programmeur. Si vous écrivez des bêtises, le compilateur ne vous grondera pas — il générera simplement un code qui peut faire n'importe quoi. L'UB est le fléau du C++. Voici ce qu'il faut repérer lors de la revue :
\n\n- \n
- Dépassement de tableau :
arr[10]pour un tableau de 10 éléments. \n - Utilisation d'une variable après déplacement :
std::moven'est pas magique, l'objet après déplacement est dans un état valide mais indéfini. \n - Débordement d'entier signé :
INT_MAX + 1— c'est un UB ! (Contrairement à Java, où c'est juste un wrap-around). \n - Référence pendante : retour d'une référence à une variable locale. \n
Exemple d'UB (cherchez-le lors du code review) :
\n\nint& getValue() {\n int x = 42;\n return x; // UB ! x est détruit après la sortie de la fonction\n}\n\nvoid example() {\n int& ref = getValue();\n std::cout << ref; // Peut afficher 42, ou des déchets, ou planter\n}\n\n\nConseil pour le relecteur : si vous voyez de l'arithmétique avec int, surtout dans des boucles ou lors de la manipulation de tailles — vérifiez s'il n'y aura pas de débordement. Il est préférable d'utiliser size_t pour les indices et std::ssize() pour une comparaison sécurisée.