Lecture 5: Debugging Flashcards
(9 cards)
Welche Compiler-Optionen werden empfohlen, um möglichst viele potenzielle Fehler schon beim Übersetzen zu erkennen?
-Wall und -Wextra. Sie aktivieren umfangreiche Warnungen; Ziel ist, einen Codezustand ohne Warnungen zu erreichen, was die Qualität deutlich erhöht.
Warum ist ein „warnungsfreier“ Build ein Debugging-Ziel?
Warnungen weisen früh auf mögliche Fehlerquellen hin; eliminiert man sie, sinkt die Wahrscheinlichkeit späterer Laufzeit-Bugs.
Wie kann man mit printf debuggen und welche Rolle spielt dabei der Output-Buffer?
Durch Ausgeben von Variablenwerten mit printf. Da Ausgaben gepuffert sind, sollte man bei Absturz-verdächtigem Code fflush(stdout); aufrufen, um die Ausgabe sofort sichtbar zu machen.
Welchen Nachteil hat häufiges fflush(stdout); beim Debugging?
Es sichert zwar sofortige Ausgabe, kann aber die Performance deutlich verschlechtern.
Was ist eine Invariante und wie helfen Assertions dabei?
Eine Invariante ist eine Bedingung, die im gesamten Programmlauf wahr sein muss. assert(condition); prüft sie zur Laufzeit und signalisiert logisch falsche Zustände sofort.
Welche Header-Datei wird für assert benötigt und wie deaktiviert man Assertions in Release-Builds?
include <assert.h>; mit dem Compiler-Schalter -DNDEBUG werden Assertions übersprungen. </assert.h>
Warum sollten Assertions nicht als reguläre Fehlerbehandlung genutzt werden?
Sie dienen dem Debugging, um Programmierfehler aufzudecken. Im Produktivcode sollen definierte Fehlerwege verwendet werden, nicht Programmabbrüche via assert.
Welches Problem deckt das Beispiel der fehlerhaften factorial-Funktion mithilfe von assert auf?
Die Assertion assert(n >= 0); enthüllt, dass ein Basisfall fehlt; ohne ihn führt die Rekursion zum Stack-Overflow.
Was ist der Hauptvorteil von Compiler-Warnungen gegenüber Laufzeit-Debugging?
Fehler werden schon vor dem Ausführen entdeckt, was Debugging-Zeit spart und stabilere Builds schafft.