Alweer geen Excel

Undefined human behavior

Arnout van Kempen schrijft in deze rubriek over pret maken met computers. Hij gooit het na een reeks over Pascal over een andere boeg en gaat aan de slag met C.

We bespraken undefined behavior. Dat gebeurt als de compiler een formule niet afkeurt als fout, maar de regels van C niet exact worden gevolgd. Je mag dan als programmeur in beginsel niet verwachten dat je programma zal doen wat je vooraf bedacht had.

Naast de compiler is er nog een bron van onvoorspelbaar gedrag: de mens. Daar kijken we vandaag naar. In veel programma’s wil je graag dat de gebruiker gegevens kan invoeren, vaak via toetsenbord. C kent daarvoor een functie: scanf().

Dat werkt eigenlijk vrij simpel.

#include <stdio.h>

int main() {
char naam[10];
scanf(“%s”, naam);
printf(“Hallo %s”,naam);
return 0;
}

Probeer het eens, let wel op dat je een naam invoert van minder dan tien letters. Werkt precies zoals je zou verwachten, nietwaar? Maar wat gebeurt er als je een langere naam invoert? Probeer het maar. Met spaties, zonder spaties. Zelfs als er op het oog niets mis gaat, is het goed te bedenken hoe C met variabelen omgaat. Een langere tekst wordt opgeslagen in het geheugen dat voor de variabele is gereserveerd. Maar als dat niet genoeg is, gaat het vrolijk verder in niet voor onze variabele gereserveerd geheugen, dus overschrijft potentieel een andere variabele. Dat is bijna vragen om ellende, of feest voor hackers.

Je kan hier nog wel iets aan verbeteren:

#include <stdio.h>

int main() {
char naam[10];
scanf(“%9s”, naam);
printf(“Hallo %s”,naam);
return 0;
}

Probeer het maar.
Is het hiermee opgelost? Niet helemaal. Want wat nu als we niet om tekst vragen, maar om cijfers?

#include <stdio.h>

int main() {
int x;
scanf(“%d”, &x);
printf(“plus 1 = %d\n ”,x+1);
return 0;
}

Negeer even waarom die & nodig is, dat komt nog. Probeer dit programma uit. Voer een getal in. Voer tekst in. Het gaat problemen geven.

Het grote probleem van scanf() is, dat het geschreven is vanuit een kennelijk geloof dat gebruikers gewoon doen wat ze wordt gevraagd, of programmeurs hun problemen zelf oplossen. Je kan wel een beetje sturen, maar te beperkt om een veilig programma mee te bouwen. C geeft je een kettingzaag, zorg zelf maar dat dat goed afloopt.

Overigens had je nog gets(), daar zit niet eens een mogelijkheid om lengte te bepalen bij, zodat je echt totale chaos binnen haalt. Gets() is zo gevaarlijk dat het zelfs maar uit de taaldefinitie is gehaald.
Waarom die dan toch genoemd? Omdat C programmeurs veelal gebruik maken van een verbeterde versie van gets(), die ook beter is dan scanf(). Dit is fgets(), wat staat voor file-gets. Hiermee kan je input binnenhalen waarbij de input van de gebruiker weliswaar vrijongecontroleerd binnen komt, maar de programmeur de ruimte heeft om zelf problemen af te vangen, voor de compiler je voet eraf schiet.

Arnout van Kempen is naast computernerd ook directeur compliance & risk bij aaff. Hij schrijft op persoonlijke titel.

Gerelateerd

reacties

Reageer op dit artikel

Spelregels debat

    Aanmelden nieuwsbrief

    Ontvang elke werkdag (maandag t/m vrijdag) de laatste nieuwsberichten, opinies en artikelen in uw mailbox.

    Bent u NBA-lid? Dan kunt u zich ook aanmelden via uw ledenprofiel op MijnNBA.nl.