En C, il n'y a pas de support intégré pour les exceptions, la gestion des erreurs est réalisée de plusieurs manières :
Retour de code d'erreur (généralement via la valeur de la fonction) Exemple :
int read_file(const char *name) { FILE *f = fopen(name, "r"); if (!f) return -1; // Erreur // ... fclose(f); return 0; // Succès }
Utilisation de la variable globale errno
En cas d'erreur, les fonctions standard définissent souvent la variable globale errno.
Exemple :
FILE *fp = fopen("nofile", "r"); if (!fp) { perror("Erreur de fichier"); // errno définit la raison }
setjmp/longjmp — un mécanisme pour lancer des "exceptions" (le contexte d'exécution est sauvegardé et restauré) Utilisé pour des cas complexes (par exemple, une terminaison anormale entre niveaux). Utilisé rarement car cela complique le code et peut entraîner des fuites de ressources.
#include <setjmp.h> jmp_buf buf; if (setjmp(buf) == 0) { // ... longjmp(buf, 1); // Revient à if (setjmp(...)) } else { // Gestion d'erreur }
Que va afficher le code suivant ?
#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; }
Réponse :
setjmp retourne 0 et la fonction func est appelée.longjmp(buf, 5) est exécuté, l'exécution revient à setjmp, qui retourne maintenant 5.val=0
val=5
Histoire Dans une bibliothèque, un mécanisme manuel de nettoyage des ressources en cas d'erreur a été implémenté uniquement par code de retour. Mais le programmeur a oublié de gérer l'erreur lors d'un retour non pas du fil principal, mais d'un callback (via setjmp/longjmp), ce qui a entraîné des fuites de mémoire et des blocages de fichiers.
Histoire Dans une application réseau, la vérification de
errnoa été omise après une opération de socket. En conséquence, un faux diagnostic s'est produit : la variableerrnoa conservé une ancienne valeur incorrecte de la fonction précédente.
Histoire L'équipe a réalisé une complexité d'imbrication avec de nombreux points de retour de code d'erreur, mais n'a pas respecté la convention sur les valeurs de retour (zéro/valeurs négatives). Certaines erreurs étaient interprétées comme réussies, entraînant des défaillances imprévisibles du service.