ProgrammatieC ontwikkelaar

Hoe wordt foutafhandeling in de C-taal geïmplementeerd? Wat zijn de verschillen tussen setjmp/longjmp, errno en het retourneren van een foutcode? Wanneer moet je welke benadering gebruiken?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord

In de C-taal is er geen ingebouwde ondersteuning voor uitzonderingen, foutafhandeling wordt geïmplementeerd op de volgende manieren:

  1. 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 }
  2. 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 }
  3. 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 }
  • Retournieren van een foutcode — de belangrijkste manier, eenvoudig en veilig.
  • errno — handig voor bibliotheekfuncties.
  • setjmp/longjmp — voor specifieke gevallen (complexe bibliotheken of interpreters).

Vraag met een valstrik

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:

  • Bij de eerste aanroep van setjmp retourneert het 0 en wordt de functie func aangeroepen.
  • Hierin gebeurt longjmp(buf, 5), de uitvoering gaat terug naar setjmp, dat nu 5 retourneert.
  • Einduitvoer:
    val=0
    val=5
    

Voorbeelden van echte fouten door onbekendheid met de nuances van het onderwerp


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 errno na een socketbewerking overgeslagen. Hierdoor ontstond valse diagnose: de variabele errno behield 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.