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").