next up previous contents index
suivant: Files monter: main précédent: Piles   Table des matières   Index


Traitement des erreurs

Le traitement des erreurs est l'une des questions les plus critiques en ingénierie du logiciel. C ne proposait pas de mécanisme approprié pour ce traitement, contrairement à quelques autres langages, comme Ada, CAML, C++ ou Java, qui disposent tous d'une notion d'exception.

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(const stack_data& x, stack& p) {
  if (p.height == MAX) {
    cout << "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 cerr :


    cerr << "erreur : pile pleine\n";

A cette solution radicale, on préfère généralement un mécanisme d'exception qui permet à une fonction utilisant push de décider ce qu'elle doit faire pour traiter cette situation détectée à l'intérieur de push. Ce mécanisme s'accomplit en deux phases : le déclenchement et la récupération.


#include <exception>                         // déclare l'exception

void push(const stack_data& x, stack& p) {
  if (p.height >= MAX) throw exception();    // déclenchement
  p.content[p.height] = x;                   // situation normale
  ++ p.height;
}

L'exécution du throw provoque d'une part la sortie immédiate de la fonction, et d'autre part le dépilage des appels jusqu'à ce qu'apparaisse un bloc d'activation d'une fonction contenant un catch : l'exception est donc propagée le long de la chaîne d'appels tant qu'elle n'est pas récupérée. Ce mécanisme de transmission est distinct du mécanisme usuel de retour d'une fonction. Si l'exception n'est jamais récupérée, le programme termine anormalement.

La récupération et le traitement sont réalisés en plaçant les appels susceptibles de déclencher une exception dans un try ... catch :


  try {                              // 
    push(4, p);                      // appel protégé
  } catch (exception e) {            // récupération d'exception
    cerr << "pile pleine" << "\n";   // traitement de l'exception
    exit(1);                         // 
  }

Ce style de programmation est nécessaire dans des logiciels qui doivent être robustes (sans parler de véritables problèmes de sécurité).


next up previous contents index
suivant: Files monter: main précédent: Piles   Table des matières   Index
R Lalement