Accès rapide :
Tester les valeurs de retour
La variable errno
Nettoyer avant de quitter
Une discipline de programmation
Le langage C ne propose pas de mécanisme d'exceptions. La gestion des erreurs repose donc sur des conventions : une fonction renvoie une valeur particulière pour signaler l'échec, et le programme appelant doit tester cette valeur immédiatement. Ignorer un code de retour est une source de bugs très fréquente.
Chaque fonction définit sa propre convention. Une allocation mémoire retourne NULL en cas d'échec. Une fonction
de lecture peut retourner EOF ou -1. Une fonction de la famille printf retourne souvent
un nombre négatif en cas d'erreur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <stdio.h> #include <stdlib.h> int main() { int * values = malloc( 100 * sizeof *values ); if ( values == NULL ) { fprintf( stderr, "Allocation impossible\n" ); return EXIT_FAILURE; } free( values ); return EXIT_SUCCESS; } |
Certaines fonctions de la librairie standard et beaucoup de fonctions POSIX renseignent la variable globale
errno lorsqu'une erreur survient. Cette variable contient un code numérique.
Pour afficher un message lisible, vous pouvez utiliser perror.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
#include <stdio.h> #include <stdlib.h> int main() { FILE * inputFile = fopen( "missing.txt", "r" ); if ( inputFile == NULL ) { perror( "fopen" ); return EXIT_FAILURE; } fclose( inputFile ); return EXIT_SUCCESS; } |
Un programme C doit libérer explicitement les ressources qu'il a obtenues : mémoire dynamique, fichiers ouverts, verrous, buffers temporaires, et ainsi de suite. Quand plusieurs opérations peuvent échouer, il est souvent plus lisible de centraliser le nettoyage en fin de fonction.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#include <stdio.h> #include <stdlib.h> int loadFile( const char * filename ) { FILE * inputFile = NULL; char * buffer = NULL; int result = EXIT_FAILURE; inputFile = fopen( filename, "r" ); if ( inputFile == NULL ) goto cleanup; buffer = malloc( 1024 ); if ( buffer == NULL ) goto cleanup; result = EXIT_SUCCESS; cleanup: free( buffer ); if ( inputFile != NULL ) fclose( inputFile ); return result; } |
En C, la gestion des erreurs n'est pas un détail que l'on ajoute à la fin. Elle fait partie du style de programmation : chaque appel important est vérifié, chaque ressource obtenue est libérée, et chaque fonction documente clairement ce qu'elle renvoie en cas d'échec.
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :