next up previous contents
Next: About this document ... Up: Les exceptions Previous: Sémantique d'un traitement d'exceptions

Propagation d'exceptions

Que se passe-t-il si l'unité qui lève une exception ne prévoit pas de traitement pour celle-ci? Quel est le comportément d'un sous-programme qui lève une exception au cours de son exécution?

Exemple 3:

procedure principal is
   z,x,y : integer; 
   Division_par_zero : exception;
   function division(x,y: integer) return integer is
   begin
      if y=0 then raise Division_by_zero;
      else  return (x/y);
      end if;
   end division;
begin
   put("Entrez un entier:  "); get(x); 
   put("Entrez un entier:  "); get(y);
   z := division(x,y);    --- Appel de la fonction
   put("Le resultat de la division de  "); 
   put(x,2); put(" par  "); put(y,2); 
   put(" est  "); put(z);
exception
   when Data_Error => 
        put_line("Entree invalide. Au revoir");
   when Division_par_zero => 
        put_line("Division indefinie: le diviseur est nul. Au revoir");
end principal;

La fonction division(x,y) calcule x/y pour deux entiers x et y, sauf si y et nul, auquel cas elle lève l'exception Division_par_zero. Le corps de division ne contient pas de traitement d'exception. Si elle lève Division_par_zero, cet exception est propagée dynamiquement. Cela signifie que l'unité couramment exécutée - ici la fonction division - est inmédiatement terminée, et que Division_par_zero est lévée à nouveau, mais cette fois à l'endroit où l'appel pour division a été exécutée. Dans notre exemple, l'exception est propagée (lévée à nouveau) à l'endroit signalé par un commentaire dans le texte. Par la suite, le contrôle est transféré vers le traitement pour Division_par_zero dans le bloc du programme principal. De manière générale, la propagation dynamique d'un exception se fait selon deux cas:

Dans les deux cas, ce processus de rembobinage se rèpete jusqu'à atteindre soit une unité contenant un traitement pour cet exception, soit le niveau le plus haut. Si un traitement d'exception adéquat est trouvé, l'exception est traitée. Sinon, l'unité du programme principal est atteinte, son exécution est abandonée, et l'environnement d'exécution envoi un message qui signale le nom de l'exception et l'échec dans la tentative traitement.

Exemple 4:

procedure teste_date is
  -- Ce programme teste si une date saisie est correcte.
  Mois_invalide : exception;
  J, M, A, Jl, Ml, Al : Integer;
  -- Cette fonction calcule le nbe de jours d'un mois.
  function Jours_Mois(M, A : Integer) return Integer is
     --- Fonction locale qui teste si une annee est bissextile
     function Est_Bissextile(Annee: Integer) return Boolean is
      ....
     end Est_Bissextile;
   begin --- debut de Jours_Mois
     case M is
       when 4 | 6 | 9 | 11 => return(30);
       when 2 => if Est_Bissextile(A) then return(29);
                 else return(28);
                 end if;
       when 1 | 3 | 5 | 7 | 8 | 10 | 12  => return(31);
       when others => raise Mois_invalide;
     end case;
   end Jours_Mois;
   -- Teste si une date est correcte
   function Date_Correcte(J,M,A : Integer) return Boolean is
   begin
     if    (J < 1)             then raise Jour_invalide;
     elsif (A < 1800)          then raise Annee_invalide;
     elsif J<= Jours_Mois(M,A) then return true
     else                      raise Jour_inexistant;
     end if;
   end Date_Correcte;
   -- Programme Principal
begin
   -- Saisie de la date
   put("Entrez un numero de jour: "); get(J);
   put("Entrez un numero de mois: "); get(M);
   put("Entrez une annee "); get(A);
   if Date_correcte(J,M,A) then put("La date saisie est correcte");
   end if;
exception
  when Data_error => put_line("Les entrees non entieres sont invalides ");
  when Jour_invalide => 
     put_line("Le jour saisi doit etre positif");
  when Mois_invalide =>
     put_line("Le mois saisi doit etre compris entre 1 et 12");
end;

Que se passe-t-il si l'on saisit la date 0/10/2000? Les valeur des variables sont: J=0, M=10, A= 2000. L'appel Date_correcte(J,M,A) est réalisé par le programme principal. Puisque la valeur de J est inférieure à 1, cette fonction lève l'exception Jour_invalide. Comme il n'y a pas de traitement dans le corps de la fonction, l'exception est à nouveau lévée au point de l'appel. Ainsi, on cherche un traitement dans le bloc du programme principal, puis l'instruction put_line("Le jour saisi doit etre positif") est exécutée et le programme termine.

Que se passe-t-il si l'on saisit la date 30/2/2000? Les valeur des variables sont: J=30, M=13, A= 2000. Le programme principal fait l'appel Date_correcte(J,M,A). Cette fonction à son tour invoque Jours_Mois(M,A) lors du test J <= Jours_Mois(M,A). Puique M=13, Jours_Mois lève l'exception Mois_invalide sans qu'il y ait de traitement fourni dans son corps. Par conséquent, l'exception est propagée dans le corps de Date_Correcte où elle n'est toujours pas traitée. Elle est ensuite propagée vers le bloc principal où cette fois elle est traitée avec l'instruction put_line("Le mois saisi doit etre compris entre 1 et 12").


next up previous contents
Next: About this document ... Up: Les exceptions Previous: Sémantique d'un traitement d'exceptions
Maria-Viginia Aponte
2001-11-21