Debuggen

Programmeerfouten

Bij het programmeren worden er onvermijdelijk fouten gemaakt. Men maakt onderscheid tussen twee types:

De meeste compilers genereren waarschuwingen indien de code syntactisch wel klopt, maar potentieel gevaarlijk is (de compiler vermoedt dat de programmeur iets over het hoofd gezien heeft, bv. een initalisatie van een variabele). Het is een heel slechte gewoonte om deze waarschuwingen te negeren (zoals vaak gebeurt in een interactieve omgeving, waarbij een run-knop zowel compilatie als uitvoeren betekent)!!

Men zegt wel eens dat statische fouten het gevolg zijn van een tikfout, en dynamische van een denkfout, maar dit klopt niet. Een tikfout kan aanleiding geven tot run-time fouten (denk bv. aan een fout in een wiskundige uitdrukking, bv. een vergeten minteken). Evengoed kunnen bepaalde logische fouten door de compiler gedetecteerd worden, bv. een variabele gebruiken voor ze geinitialiseerd werd.

Een bug (Engels: beestje, insect) wordt soms gebruikt als synoniem voor dynamische fout, maar meestal bedoelt men meer specifiek een fout die pas laat opgemerkt wordt (bv. indien het programma al volop in gebruik is), of die zeer moeilijk oplosbaar is.

Het iteratief proces van fouten zoeken en oplossen noemt men debuggen (zeg maar "ontluizen" of "ontvlooien")

Verwar het begrip exception (exceptie of uitzondering) niet met programmeerfout. Een exceptie is een uitzonderlijke omstandigheid (bv. het ontbreken van een invoerfile) die door een programma tijdens de uitvoering speciaal behandeld wordt (d.m.v. een try-catch mechanisme).

Hoe fouten oplossen?

Om statische fouten aan te pakken moet men uiteraard de compilerboodschappen bekijken. Soms is de fout evident, maar het kan ook zijn dat een simpele fout een waterval aan vreemde foutboodschappen induceert, bv. indien een accolade vergeten werd. Daarom: tracht de fouten in volgorde op te lossen (eerst voorkomende fout eerst), en compileer eventueel herhaaldelijk opnieuw, zeker bij structurele veranderingen.

Om dynamische fouten te verbeteren (debuggen) bestaat er geen standaardaanpak. Soms is het onmiddellijk duidelijk waar en waarom een fout optreedt, maar vaak vraagt dit wat zoekwerk (typisch voorbeeld: een "segmentation fault" treedt op indien je de waarde van een nul-pointer opvraagt; het is meestal moeilijk op te sporen waar deze pointer de foutieve waarde gekregen heeft)

Indien het programma fouten maakt onder bepaalde omstandigheden, bv. bij bepaalde input, loont het vaak de moeite d.m.v. "trial and error" een duidelijk beeld te krijgen van het "geldigheidsgebied" van het programma.

Indien de oorzaak van de fout niet direct duidelijk is, is het interessant om de waarde van bepaalde variabelen op bepaalde plaatsen in het programma na te gaan, en te controleren of ze voldoen aan de verwachtingen (bv. wordt een teller te groot?, wordt een deler nul?...)

Onervaren programmeurs doen dit meestal door "print"-opdrachten (bv. cout in C++) tussen te voegen op strategische plaatsen (bv. in een lus), eventueel in een if/else om teveel output te vermijden. Deze methode levert meestal resultaat, maar is heel tijdrovend en vervelend (men moet telkens hercompileren, en achteraf alle print-opdrachten weer verwijderen).

De beste aanpak is wellicht het gebruik van een apart programma - de debugger - waarmee je het programma stap voor stap kunt uitvoeren en op elk moment de waarde van variabelen inspecteren, zonder de code te wijzigen! Onderzoek wijst uit dat het leeuwendeel van de programmeertijd gaat naar het opzoeken en verbeteren van fouten. Het is dan ook raadzaam wat tijd te investeren in het leren werken met een debugger.

De meeste debuggers hebben een command-line versie en een grafische versie. De grafische versie is gemakkelijk en volstaat in de meeste gevallen. Voor volledige controle kun je de command-line versie gebruiken, maar - uiteraard - moet je dan de commando's leren.

Vaak is de debugger ingebouwd in een IDE (integrated development environment), bv. Dev-C++ of Visual Studio. Bijna altijd is de debugger ook los van een IDE toegankelijk.

Debuggen in Dev-C++

Meer uitleg over debuggen in Dev-C++ vind je hier.

[W. Schepens sept. 2006]