Einleitung: Warum Code-Review auf C++ nichts für schwache Nerven ist
\n\nC++ ist eine Sprache, die dem Programmierer unglaubliche Macht verleiht. Aber wie Onkel Ben aus «Spider-Man» sagte: «Mit großer Macht kommt große Verantwortung.» Und wenn Sie in Python versehentlich int und str mischen und nur eine Exception erhalten, kann derselbe Fehler in C++ zu undefiniertem Verhalten (UB) führen, das sich erst einen Monat später um 3 Uhr morgens auf dem Server des Kunden zeigt.
Code-Review auf C++ ist kein Häkchen in Jira. Es ist Ihr Schutzschild vor Segmentation Fault, Speicherlecks und langsamem Code, der sich wie eine Schnecke bewegt. Viele Entwickler (besonders diejenigen, die von Java oder Python kommen) denken, Code-Review sei die Überprüfung von Stil und Variablennamen. Bei C++ geht es tiefer. Hier müssen Sie in die Seele des Programms blicken: auf Speicherverwaltung, auf RAII, auf const-correctness und darauf, ob dieser Smart Pointer Ihnen nicht ins Bein schießt.
\n\nIn diesem Artikel habe ich eine echte Checkliste für die Überprüfung von C++-Code zusammengestellt. Nehmen Sie sie zur Hand, wenn Sie Ihr nächstes Code-Review durchführen. Los geht's!
\n\n1. Speicherlecks und Ressourcenverwaltung (RAII)
\n\nDies ist das Allerheiligste von C++. Wenn Sie new ohne delete sehen, ist das eine rote Flagge. Aber im modernen C++ (C++11 und neuer) sollten wir new gar nicht mehr manuell schreiben. Verwenden Sie Smart Pointer: std::unique_ptr, std::shared_ptr. Wenn ein Entwickler rohe Zeiger (int*) für den Besitz einer Ressource verwendet, ist das ein Grund, eine Frage zu stellen.
Beispiel für schlechten Code (rote Flagge):
\n\nvoid process() {\n int* data = new int[1000];\n // ... irgendein Code ...\n if (error) {\n return; // LECK! delete wurde nicht aufgerufen\n }\n delete[] data;\n}\n\n\nBeispiel für guten Code (RAII):
\n\nvoid process() {\n std::vector<int> data(1000);\n // ... Code ...\n if (error) {\n return; // Alles ok, der Vektor räumt den Speicher selbst auf\n }\n}\n\n\nWas Sie beim Code-Review auf C++ prüfen sollten:
\n- \n
- Gibt es
new/deleteim Code? Wenn ja, warum? Warum nichtstd::make_unique? \n - Werden
std::unique_ptrfür exklusiven Besitz verwendet? \n - Wird
std::shared_ptrper Wert übergeben, wo eine Referenz ausreichen würde (das ist aufgrund des atomic counter teuer)? \n - Gibt es Speicherlecks bei Ausnahmen (exception safety)? \n
2. Undefiniertes Verhalten (Undefined Behavior)
\n\nIn C++ vertraut der Compiler dem Programmierer. Wenn Sie Unsinn schreiben, wird der Compiler Sie nicht ausschimpfen – er generiert einfach Code, der alles Mögliche tun kann. UB ist die Geißel von C++. Hier ist, worauf Sie beim Review achten sollten:
\n\n- \n
- Array-Index außerhalb der Grenzen:
arr[10]für ein Array mit 10 Elementen. \n - Verwendung einer Variable nach dem Verschieben:
std::moveist keine Magie, das Objekt befindet sich nach dem Verschieben in einem gültigen, aber undefinierten Zustand. \n - Signed Integer Overflow:
INT_MAX + 1ist UB! (Im Gegensatz zu Java, wo es einfach nur umläuft). \n - Dangling Reference: Rückgabe einer Referenz auf eine lokale Variable. \n
Beispiel für UB (suchen Sie danach beim Code-Review):
\n\nint& getValue() {\n int x = 42;\n return x; // UB! x wird nach Verlassen der Funktion zerstört\n}\n\nvoid example() {\n int& ref = getValue();\n std::cout << ref; // Kann 42 ausgeben, aber auch Müll oder einen Crash verursachen\n}\n\n\nTipp für den Reviewer: Wenn Sie Arithmetik mit int sehen, besonders in Schleifen oder bei der Arbeit mit Größen – prüfen Sie, ob es zu einem Überlauf kommen kann. Verwenden Sie besser size_t für Indizes und std::ssize() für sichere Vergleiche.