Zum Inhalt springen
Topos Uranos

Zusammenfassung

Diese Lektion schließt die achte Einheit und mit ihr den Kurs ab. Sie fasst zusammen, was die drei Lektionen der Einheit erreicht haben; sie rekonstruiert die Kette der Begriffe, die von der Schnittstelle eines Moduls zum Debugging als Methode führt; sie trennt, was davon in jeder Sprache gilt, von dem, was C++ eigen ist; sie zeigt die Verletzung der One-Definition-Rule (Regel der einen Definition), die niemand diagnostiziert, und stellt das gesamte undefinierte Verhalten des Kurses in einer Liste zusammen, jeweils mit dem, was den Fall aufdeckt; sie wiederholt in ihrem Abschlusstest die Fertigkeiten des Eingangstests; sie stellt sechs Herausforderungen, die die Einheit verbinden; und sie endet mit dem Abschlussprojekt des Kurses, präzise spezifiziert, mit seinem Bewertungsraster, in vier Etappen, jede mit einer geprüften Referenzlösung.

Lernziele

  1. Ein Programm in mehrere Module mit Headern, Include-Guards und Verträgen gliedern, es getrennt kompilieren und die Meldungen des Linkers diagnostizieren.
  2. Ein Modul von seiner Spezifikation aus testen, mit einem Programm automatisierter Tests, das unter den Sanitizern läuft, und mit Zusicherungen prüfen, was nicht eintreten kann.
  3. Einen Fehler mit einer Methode (reproduzieren, reduzieren, Hypothesen aufstellen, per Bisektion eingrenzen) und mit dem Debugger lokalisieren und die Untersuchung dokumentieren.
  4. Das undefinierte Verhalten erkennen, das der Kurs gezeigt hat, jeweils mit dem, was den Fall aufdeckt, und die Verletzung der One-Definition-Rule, die niemand diagnostiziert.
  5. Den ganzen Kurs in einem Projekt zusammenführen: ein Programm zur Verwaltung tabellarischer Daten spezifizieren, zerlegen, bauen, testen, seine Kosten messen und debuggen.

Was die Einheit erreicht hat

Die Einheit hatte sich vorgenommen zu lehren, wie man Programme organisiert, überprüft und debuggt, die weder in eine Datei noch in den Kopf passen. Das Vorhaben ist erfüllt, gestützt auf das, was die Einführung als bekannt vorausgesetzt hat: Deklaration und Definition, Kompilierung und Linken, den Vertrag, die Invariante und die binäre Suche. Das Programm des Bücherkatalogs, mit dem die Einheit begann, passte in eine Datei, kopierte parseInt ein weiteres Mal und ließ „Cien años de soledad“ stillschweigend aus, weil es < schrieb, wo die Spezifikation „beide eingeschlossen“ sagte; am Ende dieser Lektion wird es als Abschlussprojekt neu geschrieben: vier Module mit Verträgen, ein Hauptprogramm, das Befehle beantwortet, und ein Testprogramm mit fünfundzwanzig Fällen. Zwei dieser Fälle, „zwischen, Grenzen“ und „zwischen, ein Jahr“, schlagen mit der Bedingung des ursprünglichen Programms fehl, und deshalb könnte der Fehler nicht zurückkehren, ohne dass es jemand bemerkte.

Mehrere Dateien und eigene Bibliotheken

Die Lektion Mehrere Dateien und eigene Bibliotheken teilte ein Programm in einen Header, der deklariert, eine Implementierungsdatei, die definiert, und eine main.cpp, die verwendet. Sie stellte die Include-Guards vor, die die doppelte Einbindung innerhalb einer Übersetzungseinheit verhindern; die One-Definition-Rule, die „multiple definition“ und „undefined reference“ erklärt und inline seinen heutigen Sinn als Erlaubnis gibt; die getrennte Kompilierung mit -c, die nur die Objekte neu kompiliert, deren Quellen oder Header sich geändert haben; und eine eigene Bibliothek mit Funktionen aus früheren Lektionen.

Testen

Die Lektion Testen lehrte, die Fälle aus einer Spezifikation abzuleiten, nach Bereichen, Grenzen und Sonderfällen, mit dem erwarteten Ergebnis auf einem anderen Weg berechnet; ein Programm automatisierter Tests zu schreiben, das nur die Fehlschläge meldet und mit Code 0 oder 1 endet; assert für das zu verwenden, was nicht eintreten kann, im Wissen, dass -DNDEBUG es samt seiner Bedingung löscht; zur Kompilierzeit mit static_assert und constexpr zu testen; und die Tests mit den Sanitizern auszuführen (dem für Speicherfehler, AddressSanitizer, und dem für undefiniertes Verhalten, UndefinedBehaviorSanitizer). Alles ruht auf Dijkstras Warnung: Ein Test zeigt die Anwesenheit von Fehlern, nie ihre Abwesenheit.

Debuggen

Die Lektion Debuggen stellte das Debugging als experimentelle Methode vor: das Fehlverhalten reproduzieren, falsifizierbare Hypothesen aufstellen, zwischen ihnen mit Experimenten entscheiden und das verdächtige Intervall per Bisektion eingrenzen. Sie entwickelte das Instrument (-g ohne Optimierung, die Konfiguration von Visual Studio Code auf den drei Systemen, eine echte Sitzung mit GDB, einfache und bedingte Haltepunkte, die Schritte und den Aufrufstapel) und die Strategien, die mehr wert sind als es: den Fall reduzieren, mit Zusicherungen den letzten korrekten Punkt suchen und beim ersten eigenen Rahmen des Sanitizer-Berichts beginnen.