In de C-taal is er geen ingebouwde ondersteuning voor uitzonderingen, foutafhandeling wordt geïmplementeerd op de volgende manieren:
Retournieren van een foutcode (meestal via de functiewaarde) Voorbeeld:
int read_file(const char *name) { FILE *f = fopen(name, "r"); if (!f) return -1; // Fout // ... fclose(f); return 0; // Succes }
Gebruik van de globale variabele errno
Bij een fout stellen standaardfuncties vaak de globale variabele errno in.
Voorbeeld:
FILE *fp = fopen("nofile", "r"); if (!fp) { perror("Bestand fout"); // errno definieert de reden }
setjmp/longjmp — mechanisme voor het gooien van een "uitzondering" (de uitvoeringscontext wordt opgeslagen en hersteld) Wordt gebruikt voor complexe gevallen (bijvoorbeeld tussen niveaus noodstop). Wordt zelden gebruikt omdat het de code complex maakt en kan leiden tot resource-lekken.
#include <setjmp.h> jmp_buf buf; if (setjmp(buf) == 0) { // ... longjmp(buf, 1); // Gaat terug naar if (setjmp(...)) } else { // Foutafhandeling }
Wat zal de volgende code afdrukken?
#include <stdio.h> #include <setjmp.h> jmp_buf buf; void func() { longjmp(buf, 5); } int main() { int val = setjmp(buf); printf("val=%d\n", val); if (val == 0) func(); return 0; }
Antwoord:
setjmp retourneert het 0 en wordt de functie func aangeroepen.longjmp(buf, 5), de uitvoering gaat terug naar setjmp, dat nu 5 retourneert.val=0
val=5
Verhaal In een bibliotheek was er een handmatig mechanisme geïmplementeerd voor het opruimen van resources bij een fout alleen op basis van de foutcode. Maar de programmeur vergat de fout af te handelen bij het retourneren niet uit de hoofdtak, maar uit een callback (via setjmp/longjmp), waardoor er geheugenlekken en bestandsvergrendelingen ontstonden.
Verhaal In een netwerktoepassing werd de controle op
errnona een socketbewerking overgeslagen. Hierdoor ontstond valse diagnose: de variabeleerrnobehield een oude, onjuiste waarde van de vorige functie.
Verhaal Het team implementeerde een complexe geneste structuur met vele punten voor het retourneren van foutcodes, maar hield zich niet aan de conventie over retourwaarden (nul/negatieve waarden). Sommige fouten werden geïnterpreteerd als succesvol, wat leidde tot onvoorspelbare falingen van de service.