Le traitement des erreurs est l'une des questions les plus critiques en ingénierie du logiciel. Malheureusement, C ne propose pas de mécanisme approprié pour ce traitement, contrairement à quelques autres langages, comme Ada, ML ou Java, qui disposent de la notion d'exception : à part les erreurs d'arithmétique flottante (selon une norme IEEE), qui peuvent être traitées, il faut recourir à des bibliothèques d'usage difficile pour les autres types d'erreur.
Par exemple, la procédure push, qui empile un élément, doit tester si la pile n'est pas déjà pleine. Si c'est le cas, c'est une situation exceptionnelle qui doit être traitée. Une solution radicale consiste à afficher un message d'erreur et à sortir du programme, à l'aide de la fonction exit à laquelle on doit alors passer un argument entier non nul (pour distinguer cette sortie exceptionnelle du return 0; final qui indique un fonctionnement normal du main) :
void push(stack_data x, stack *p) {
if (p->height == MAX) {
printf("erreur : pile pleine\n");
exit(1);
} else {
p->content[p->height] = x;
++ p->height;
}
}
Plutôt que d'imprimer un message d'erreur sur la sortie standard, il est préférable d'utiliser la sortie d'erreur standard , appelée stderr, qu'on doit passer en premier argument à la fonction fprintf :
fprintf(stderr, "erreur : pile pleine\n");
A cette solution radicale, on préfère généralement un test qui permette à la fonction appelante de push de décider ce qu'elle doit faire pour traiter cette situation détectée à l'intérieur de push. On remplace alors la procédure (fonction retournant void) par une fonction retournant un int, interprété logiquement (0 est un échec, 1 est un succès) :
int push(stack_data x, stack *p) {
if (p->height == MAX) {
return 0;
} else {
p->content[p->height] = x;
++ p->height;
return 1;
}
}
Il appartiendra à la fonction appelante de traiter le résultat de push :
if (!push(3,&p)) {
printf("erreur : pile pleine\n");
}
Ce style de programmation est évidemment plus lourd, mais devient nécessaire dans des logiciels qui doivent être robustes (sans parler de véritables problèmes de sécurité).