Les exceptions
Cette page définit les fonctionnalités permettant de gérer les erreurs ou autres situations exceptionnelles survenant pendant l'exécution d'un programme. Une telle situation est appelée une exception. Déclencher une exception revient à abandonner l'exécution normale du programme afin d'attirer l'attention sur le fait que la situation correspondante s'est produite. L'exécution de certaines actions, en réponse à la survenue d'une exception, est appelée gestion de l'exception.
Une déclaration d'exception déclare un nom pour une exception. Une exception peut être déclenchée par une instruction raise, ou par une autre instruction ou opération propageant l'exception. Lorsqu'une exception survient, le contrôle peut être transféré à un gestionnaire d'exceptions fourni par l'utilisateur à la fin d'une instruction de bloc ou à la fin du corps d'un sous-programme, d'un paquet ou d'une unité de tâche.
Déclarations d'exception
Une déclaration d'exception déclare un nom pour une exception. Le nom d'une exception ne peut être utilisé que dans les instructions raise, les gestionnaires d'exceptions et les déclarations de renommage.
declaration_d_exception ::= liste_identifiant : exception |
Une déclaration d'exception avec plusieurs identifiants est équivalente à une séquence de déclarations d'exceptions simples. Chaque déclaration d'exception simple déclare un nom pour une exception différente. En particulier, si une unité générique inclut une déclaration d'exception, les déclarations d'exception générées implicitement par différentes instanciations de l'unité générique font référence à des exceptions distinctes (mais ont toutes le même identifiant). L'exception particulière désignée par un nom d'exception est déterminée au moment de la compilation et est la même quel que soit le nombre de fois que la déclaration d'exception est élaborée. Par conséquent, si une déclaration d'exception se produit dans un sous-programme récursif, le nom de l'exception désigne la même exception pour toutes les invocations du sous-programme récursif.
Les exceptions suivantes sont prédéfinies dans le langage; elles sont levées lorsque les situations décrites sont détectées :
Exception | Description |
---|---|
CONSTRAINT_ERROR | Cette exception est levée dans l'une des situations suivantes : lors d'une tentative de violation d'une contrainte d'intervalle, d'une contrainte d'index ou d'une contrainte discriminante; lors d'une tentative d'utilisation d'une composante d'enregistrement n'existant pas pour les valeurs discriminantes actuelles; et lors d'une tentative d'utilisation d'un composant sélectionné, d'un composant indexé, d'une tranche ou d'un attribut d'un objet désigné par une valeur d'accès, si l'objet n'existe pas parce que la valeur d'accès est nulle. |
NUMERIC_ERROR | Cette exception est levée par l'exécution d'une opération numérique prédéfinie qui ne peut pas fournir un résultat correct (dans les limites de précision déclarées pour les types réels); cela inclut le cas où une implémentation utilise une opération numérique prédéfinie pour l'exécution, l'évaluation ou l'élaboration d'une construction. |
PROGRAM_ERROR | Cette exception est levée lors d'une tentative d'appel d'un sous-programme, d'activation d'une tâche ou d'élaboration d'une instanciation générique, si le corps de l'unité correspondante n'a pas encore été élaboré. Cette exception est également levée si la fin d'une fonction est atteinte; ou lors de l'exécution d'une attente sélective n'ayant pas de partie else, si cette exécution détermine que toutes les alternatives sont fermées. Enfin, selon l'implémentation, cette exception peut être levée lors d'une tentative d'exécution d'une action erronée, et pour des dépendances d'ordre incorrectes. |
STORAGE_ERROR | Cette exception est levée dans l'une des situations suivantes : lorsque l'entreposage dynamique alloué à une tâche est dépassé; lors de l'évaluation d'un allocateur, si l'espace disponible pour la collecte des objets alloués est épuisé; ou lors de l'élaboration d'un élément déclaratif, ou lors de l'exécution d'un appel de sous-programme, si l'entreposage n'est pas suffisant. |
TASKING_ERROR | Cette exception est levée lorsque des exceptions surviennent lors de la communication intertâche. |
Remarque : les situations décrites ci-dessus peuvent survenir sans déclencher les exceptions correspondantes, si le pragma SUPPRESS a été utilisé pour donner la permission d'omettre les vérifications correspondantes.
Exemples de déclarations d'exceptions définies par l'utilisateur :
- SINGULAR : exception;
- ERROR : exception;
- OVERFLOW, UNDERFLOW : exception;
Gestionnaires d'exceptions
La réponse à une ou plusieurs exceptions est spécifiée par un gestionnaire d'exceptions :
gestionnaire_d_exceptions ::= when choix_exception || choix_exception| => sequence_d_instructions choix_exception ::= nom_exception | others |
Un gestionnaire d'exceptions apparaît dans une construction étant soit une instruction de bloc, soit le corps d'un sous-programme, d'un paquet, d'une unité de tâche ou d'une unité générique. Une telle construction sera appelée un cadre dans cette page. Dans chaque cas, la syntaxe d'un cadre possédant des gestionnaires d'exceptions comprend la partie suivante :
begin sequence_d_instructions exception gestionnaire_d_exceptions {gestionnaire_d_exceptions} end |
Les exceptions désignées par les noms d'exception donnés comme choix d'exception d'une trame doivent toutes être distinctes. Le choix d'exception autres n'est autorisé que pour le dernier gestionnaire d'exception d'une trame et comme seul choix d'exception; il représente toutes les exceptions non répertoriées dans les gestionnaires précédents de la trame, y compris les exceptions dont les noms ne sont pas visibles à la place du gestionnaire d'exception.
Les gestionnaires d'exception d'une trame gèrent les exceptions étant déclenchées par l'exécution de la séquence d'instructions de la trame. Les exceptions gérées par un gestionnaire d'exception donné sont celles nommées par les choix d'exception correspondants.
Exemple :
Remarque : les mêmes types d'instructions sont autorisés dans la séquence d'instructions de chaque gestionnaire d'exceptions que dans la séquence d'instructions de la trame. Par exemple, une instruction return est autorisée dans un gestionnaire au sein d'un corps de fonction.
Instructions raise
Une instruction raise lève une exception :
instruction_raise ::= raise [nom_de_l_exception]; |
Pour l'exécution d'une instruction raise avec un nom d'exception, l'exception nommée est levée. Une instruction raise sans nom d'exception n'est autorisée que dans un gestionnaire d'exceptions (mais pas dans la séquence d'instructions d'un sous-programme, d'un paquet, d'une unité de tâche ou d'une unité générique, délimitée par le gestionnaire); elle lève à nouveau l'exception ayant provoqué le transfert vers le gestionnaire englobant le plus interne.
Exemples :
- raise SINGULAR;
- raise NUMERIC_ERROR; -- déclencher explicitement une exception prédéfinie
- raise; -- uniquement dans un gestionnaire d'exceptions
Gestion des exceptions
Lorsqu'une exception est déclenchée, l'exécution normale du programme est abandonnée et le contrôle est transféré à un gestionnaire d'exceptions. Le choix de ce gestionnaire dépend du fait que l'exception est déclenchée pendant l'exécution des instructions ou pendant l'élaboration des déclarations.
Exceptions levées lors de l'exécution d'instructions
La gestion d'une exception levée par l'exécution d'une séquence d'instructions dépend du fait que le cadre le plus interne ou l'instruction accept entourant la séquence d'instructions est un cadre ou une instruction accept. Le cas où une instruction accept est la plus interne est décrit dans dans les prochaines sections. Le cas où un cadre est le plus interne est présenté ici.
Différentes actions ont lieu, selon que cette trame possède ou non un gestionnaire pour l'exception, et selon que l'exception est levée dans la séquence d'instructions de la trame ou dans celle d'un gestionnaire d'exceptions.
Si une exception est levée dans la séquence d'instructions d'une trame possédant un gestionnaire pour l'exception, l'exécution de la séquence d'instructions de la trame est abandonnée et le contrôle est transféré au gestionnaire d'exceptions. L'exécution de la séquence d'instructions du gestionnaire termine l'exécution de la trame (ou son élaboration si la trame est un corps de paquet).
Si une exception est levée dans la séquence d'instructions d'une trame ne possédant pas de gestionnaire pour l'exception, l'exécution de cette séquence d'instructions est abandonnée. L'action suivante dépend de la nature de la trame :
- Pour un corps de sous-programme, la même exception est levée à nouveau au point d'appel du sous-programme, sauf si le sous-programme est le programme principal lui-même, auquel cas l'exécution du programme principal est abandonnée.
- Pour une instruction de bloc, la même exception est à nouveau levée immédiatement après l'instruction de bloc (c'est-à-dire dans le cadre englobant le plus interne ou dans l'instruction accept).
- Pour un corps de paquet étant un élément déclaratif, la même exception est à nouveau levée immédiatement après cet élément déclaratif (dans la partie déclarative englobante). Si le corps du paquet est celui d'une sous-unité, l'exception est à nouveau levée à la place du stub de corps correspondant. Si le paquet est une unité de bibliothèque, l'exécution du programme principal est abandonnée.
- Pour un corps de tâche, la tâche devient terminée.
Une exception étant levée à nouveau (comme dans les cas (a), (b) et (c) ci-dessus) est dite propagée, soit par l'exécution du sous-programme, soit par l'exécution de l'instruction de bloc, soit par l'élaboration du corps du paquet. Aucune propagation n'a lieu dans le cas d'un corps de tâche. Si le cadre est un sous-programme ou une instruction de bloc et s'il a des tâches dépendantes, la propagation d'une exception n'a lieu qu'après la fin des tâches dépendantes.
Enfin, si une exception est levée dans la séquence d'instructions d'un gestionnaire d'exceptions, l'exécution de cette séquence d'instructions est abandonnée. Les actions ultérieures (y compris la propagation, le cas échéant) sont comme dans les cas (a) à (d) ci-dessus, selon la nature du cadre.
Exemple :
Si la multiplication génère une erreur NUMERIC_ERROR, le gestionnaire renvoie alors la valeur FLOAT'SAFE_LARGE. Cette valeur entraînera la génération d'autres exceptions NUMERIC_ERROR par l'évaluation de l'expression dans chacune des invocations restantes de la fonction, de sorte que pour les valeurs N élevées, la fonction renverra finalement la valeur FLOAT'SAFE-LARGE.
Exemple :
- procedure P is
- ERROR : exception;
- procedure R;
-
- procedure Q is
- begin
- R;
- ... -- situation d'erreur (2)
- exception
- ...
- when ERROR => -- gestionnaire E2
- end Q;
-
- procedure R is
- begin
- ... -- situation d'erreur (3)
- end R;
-
- begin
- ... -- situation d'erreur (1)
- Q;
- ...
- exception
- ...
- when ERROR => -- gestionnaire E1
- ...
- end P;
Les situations suivantes peuvent se produire :
- Si l'exception ERROR est levée dans la séquence d'instructions de la procédure externe P, le gestionnaire E1 fourni dans P est utilisé pour terminer l'exécution de P.
- Si l'exception ERROR est levée dans la séquence d'instructions de Q, le gestionnaire E2 fourni dans Q est utilisé pour terminer l'exécution de Q. Le contrôle sera rendu au point d'appel de Q une fois le gestionnaire terminé.
- Si l'exception ERROR est levée dans le corps de R, appelé par Q, l'exécution de R est abandonnée et la même exception est levée dans le corps de Q. Le gestionnaire E2 est alors utilisé pour terminer l'exécution de Q, comme dans la situation (2).
Notez que dans la troisième situation, l'exception levée dans R entraîne le transfert (indirect) du contrôle à un gestionnaire faisant partie de Q et n'est donc pas inclus dans R. Notez également que si un gestionnaire était fourni dans R pour le choix d'exception others, la situation (3) provoquerait l'exécution de ce gestionnaire, plutôt que l'arrêt direct de R.
Enfin, si ERROR avait été déclaré dans R, plutôt que dans P, les gestionnaires E1 et E2 ne pourraient pas fournir de gestionnaire explicite pour ERROR puisque cet identifiant ne serait pas visible dans les corps de P et Q. Dans la situation (3), l'exception pourrait cependant être gérée dans Q en fournissant un gestionnaire pour le choix d'exception others.
Remarques : Le langage ne définit pas ce qui se passe lorsque l'exécution du programme principal est abandonnée après une exception non gérée.
Les exceptions prédéfinies sont celles qui peuvent être propagées par les opérations de base et les opérateurs prédéfinis.
Le cas d'une trame étant une unité générique est déjà couvert par les règles pour les corps de sous-programmes et de paquets, puisque la séquence d'instructions d'une telle trame n'est pas exécutée mais est le modèle pour les séquences d'instructions correspondantes des sous-programmes ou des paquets obtenus par instanciation générique.
Exceptions levées lors de l'élaboration des déclarations
Si une exception est levée lors de l'élaboration de la partie déclarative d'un cadre donné, cette élaboration est abandonnée. L'action suivante dépend de la nature du cadre :
- Pour un corps de sous-programme, la même exception est levée à nouveau au point d'appel du sous-programme, à moins que le sous-programme ne soit le programme principal lui-même, auquel cas l'exécution du programme principal est abandonnée.
- Pour une instruction de bloc, la même exception est levée à nouveau immédiatement après l'instruction de bloc.
- Pour un corps de paquet étant un élément déclaratif, la même exception est levée à nouveau immédiatement après cet élément déclaratif, dans la partie déclarative englobante. Si le corps du paquet est celui d'une sous-unité, l'exception est levée à nouveau à la place du stub de corps correspondant. Si le paquet est une unité de bibliothèque, l'exécution du programme principal est abandonnée.
- Pour un corps de tâche, la tâche devient terminée et l'exception TASKING_ERROR est levée au point d'activation de la tâche.
De même, si une exception est levée pendant l'élaboration d'une déclaration de paquet ou d'une déclaration de tâche, cette élaboration est abandonnée; l'action suivante dépend de la nature de la déclaration.
- Pour une déclaration de paquet ou une déclaration de tâche, c'est-à-dire un élément déclaratif, l'exception est levée à nouveau immédiatement après l'élément déclaratif dans la partie déclarative ou la spécification de paquet englobante. Pour la déclaration d'un paquet de bibliothèque, l'exécution du programme principal est abandonnée.
Une exception étant levée à nouveau (comme dans les cas ci-dessus (a), (b), (c) et (e)) est dite propagée, soit par l'exécution du sous-programme ou de l'instruction de bloc, soit par l'élaboration de la déclaration de paquet, de la déclaration de tâche ou du corps du paquet.
Exemple d'exception dans la partie déclarative d'une instruction de bloc (cas (b)) :
Exceptions levées pendant la communication des tâches
Une exception peut être propagée à une tâche communiquant ou tentant de communiquer avec une autre tâche. Une exception peut également être propagée à une tâche appelante si l'exception est levée pendant un rendez-vous.
Lorsqu'une tâche appelle une entrée d'une autre tâche, l'exception TASKING_ERROR est levée dans la tâche appelante, à l'endroit de l'appel, si la tâche appelée est terminée avant d'accepter l'appel d'entrée ou est déjà terminée au moment de l'appel.
Un rendez-vous peut être terminé anormalement dans deux cas :
- Lorsqu'une exception est levée dans une instruction accept, mais n'est pas gérée dans un cadre interne. Dans ce cas, l'exécution de l'instruction accept est abandonnée et la même exception est levée à nouveau immédiatement après l'instruction accept dans la tâche appelée ; l'exception est également propagée à la tâche appelante au point d'appel de l'entrée.
- Lorsque la tâche contenant l'instruction accept est terminée anormalement à la suite d'une instruction abort. Dans ce cas, l'exception TASKING_ERROR est levée dans la tâche appelante au moment de l'appel d'entrée.
En revanche, si une tâche émettant un appel d'entrée devient anormale (suite à une instruction d'abandon), aucune exception n'est levée dans la tâche appelée. Si le rendez-vous n'a pas encore commencé, l'appel d'entrée est annulé. Si le rendez-vous est en cours, il se termine normalement et la tâche appelée n'est pas affectée.
Exceptions et optimisation
L'objectif de cette section est de spécifier les conditions dans lesquelles une implémentation est autorisée à effectuer certaines actions plus tôt ou plus tard que ce qui est spécifié par d'autres règles du langage.
En général, lorsque les règles du langage spécifient un ordre pour certaines actions (l'ordre canonique), une implémentation ne peut utiliser un ordre alternatif que si elle peut garantir que l'effet du programme n'est pas modifié par le réordonnancement. En particulier, aucune exception ne doit survenir pour l'exécution du programme réordonné si aucune exception ne survient pour l'exécution du programme dans l'ordre canonique. Lorsque, en revanche, l'ordre de certaines actions n'est pas défini par le langage, n'importe quel ordre peut être utilisé par l'implémentation. (Par exemple, les paramètres d'un opérateur prédéfini peuvent être évalués dans n'importe quel ordre puisque les règles ne nécessitent pas d'ordre d'évaluation spécifique.
Une liberté supplémentaire est laissée à une implémentation pour réorganiser les actions impliquant des opérations prédéfinies étant soit des opérateurs prédéfinis, soit des opérations de base autres que des affectations. Cette liberté est laissée, comme défini ci-dessous, même dans le cas où l'exécution de ces opérations prédéfinies peut propager une exception (prédéfinie) :
- Pour établir si le même effet est obtenu par l'exécution de certaines actions dans l'ordre canonique et dans un ordre alternatif, on peut supposer qu'aucune des opérations prédéfinies invoquées par ces actions ne propage une exception (prédéfinie), à ??condition que les deux exigences suivantes soient remplies par l'ordre alternatif : premièrement, une opération ne doit pas être invoquée dans l'ordre alternatif si elle n'est pas invoquée dans l'ordre canonique ; deuxièmement, pour chaque opération, le cadre englobant le plus interne ou l'instruction accept doit être le même dans l'ordre alternatif que dans l'ordre canonique, et les mêmes gestionnaires d'exceptions doivent s'appliquer.
- Dans une expression, l'association des opérateurs avec les opérandes est spécifiée par la syntaxe. Cependant, pour une séquence d'opérateurs prédéfinis de même niveau de priorité (et en l'absence de parenthèses imposant une association spécifique), toute association d'opérateurs avec les opérandes est autorisée si elle satisfait l'exigence suivante : un résultat entier doit être égal à celui donné par l'ordre canonique de gauche à droite; un résultat réel doit appartenir à l'intervalle de modèle de résultat défini pour l'ordre canonique de gauche à droite. Un tel réordonnancement est autorisé même s'il peut supprimer une exception, ou introduire une autre exception prédéfinie.
De même, une liberté supplémentaire est laissée à une implémentation pour l'évaluation d'expressions numériques simples. Pour l'évaluation d'une opération prédéfinie, une implémentation est autorisée à utiliser l'opération d'un type dont la plage est plus large que celle du type de base des opérandes, à condition que cela fournisse le résultat exact (ou un résultat dans la précision déclarée, dans le cas d'un type réel), même si certains résultats intermédiaires se situent en dehors de l'intervalle du type de base. L'exception NUMERIC_ERROR n'a pas besoin d'être levée dans un tel cas. En particulier, si l'expression numérique est un opérande d'un opérateur relationnel prédéfini, l'exception NUMERIC_ERROR n'a pas besoin d'être levée par l'évaluation de la relation, à condition que le résultat BOOLEAN correct soit obtenu.
Une opération prédéfinie n'a pas besoin d'être invoquée du tout, si son seul effet possible est de propager une exception prédéfinie. De même, une opération prédéfinie n'a pas besoin d'être invoquée si la suppression des opérations suivantes par la règle ci-dessus rend cette invocation inefficace.
Remarques : La règle (b) s'applique aux opérateurs prédéfinis mais pas aux formes de contrôle de court-circuit.
L'expression SPEED < 300_000.0 peut être remplacée par TRUE si la valeur 300_000.0 se situe en dehors du type de base de SPEED, même si la conversion implicite du littéral numérique déclencherait l'exception NUMERIC_ERROR.
Exemple :
L'évaluation de A(K) peut être effectuée avant la boucle, et éventuellement immédiatement avant l'instruction d'affectation (1) même si cette évaluation peut déclencher une exception. Par conséquent, dans le gestionnaire d'exceptions, la valeur de N est soit la valeur initiale indéfinie, soit une valeur assignée ultérieurement. En revanche, l'évaluation de A(K) ne peut pas être déplacée avant le début de la boucle car une exception serait alors gérée par un gestionnaire différent. Pour cette raison, l'initialisation de N dans la déclaration elle-même exclurait la possibilité d'avoir une valeur initiale indéfinie de N dans le gestionnaire.
Suppression des vérifications
La présence d'un pragma SUPPRESS donne la permission à une implémentation d'omettre certaines vérifications d'exécution. La forme de ce pragma est la suivante :
pragma SUPPRESS (identifiant [, [ON =>] nom]) |
L'identifiant est celui du contrôle pouvant être omis. Le nom (s'il est présent) doit être soit un nom simple, soit un nom développé et doit désigner soit un objet, un type ou un sous-type, une unité de tâche ou une unité générique ; le nom peut également être un nom de sous-programme, auquel cas il peut représenter plusieurs sous-programmes surchargés visibles.
Un pragma SUPPRESS n'est autorisé qu'immédiatement dans une partie déclarative ou immédiatement dans une spécification de paquet. Dans ce dernier cas, la seule forme autorisée est avec un nom qui désigne une entité (ou plusieurs sous-programmes surchargés) déclarée immédiatement dans la spécification de paquet. L'autorisation d'omettre la vérification donnée s'étend de l'emplacement du pragma jusqu'à la fin de la région déclarative associée à l'instruction de bloc ou à l'unité de programme la plus interne. Pour un pragma donné dans une spécification de paquet, l'autorisation s'étend jusqu'à la fin de la portée de l'entité nommée.
Si le pragma inclut un nom, l'autorisation d'omettre la vérification donnée est encore plus restreinte : elle est donnée uniquement pour les opérations sur l'objet nommé ou sur tous les objets du type de base d'un type ou sous-type nommé; pour les appels d'un sous-programme nommé; pour les activations de tâches du type de tâche nommé ; ou pour les instanciations de l'unité générique donnée.
Les vérifications suivantes correspondent aux situations dans lesquelles l'exception CONSTRAINT_ERROR peut être levée ; pour ces vérifications, le nom (s'il est présent) doit désigner soit un objet, soit un type.
Vérification | Description |
---|---|
ACCESS_CHECK | Lors de l'accès à un composant sélectionné, à un composant indexé, à une tranche ou à un attribut d'un objet désigné par une valeur d'accès, vérifiez que la valeur d'accès n'est pas nulle. |
DISCRIMINANT_CHECK | Vérifiez qu'un discriminant d'une valeur composite possède la valeur imposée par une contrainte discriminante. De plus, lors de l'accès à une composante d'enregistrement, vérifiez qu'il existe pour les valeurs discriminantes actuelles. |
INDEX_CHECK | Vérifiez que les limites d'une valeur de tableau sont égales aux limites correspondantes d'une contrainte d'index. De même, lors de l'accès à un composant d'un objet tableau, vérifiez pour chaque dimension que la valeur d'index donnée appartient à l'intervalle définie par les limites de l'objet tableau. De même, lors de l'accès à une tranche d'un objet tableau, vérifiez que l'intervalle discrète donnée est compatible avec l'intervalle définie par les limites de l'objet tableau. |
LENGTH_CHECK | Vérifiez qu'il existe un composant correspondant pour chaque composante d'un tableau, dans le cas d'affectations de tableau, de conversions de type et d'opérateurs logiques pour les tableaux de composantes booléens. |
RANGE_CHECK | Vérifiez qu'une valeur satisfait une contrainte d'intervalle. De même, pour l'élaboration d'une indication de sous-type, vérifiez que la contrainte (si présente) est compatible avec la marque de type. De même, pour un agrégat, vérifiez qu'un index ou une valeur discriminante appartient au sous-type correspondant. Enfin, vérifiez les éventuelles vérifications de contrainte effectuées par une instanciation générique. |
Les vérifications suivantes correspondent aux situations dans lesquelles l'exception NUMERIC_ERROR est levée. Les seuls noms autorisés dans les pragmas correspondants sont les noms de types numériques :
Vérification | Description |
---|---|
DIVISION_CHECK | Vérifiez que le deuxième opérande n'est pas nul pour les opérations /, rem et mod. |
OVERFLOW_CHECK | Vérifiez que le résultat d'une opération numérique ne déborde pas. |
La vérification suivante correspond aux situations dans lesquelles l'exception PROGRAM_ERROR est levée. Les seuls noms autorisés dans les pragmas correspondants sont les noms désignant des unités de tâches, des unités génériques ou des sous-programmes.
Vérification | Description |
---|---|
ELABORATION_CHECK | Lorsqu'un sous-programme est appelé, qu'une activation de tâche est réalisée ou qu'une instanciation générique est élaborée, vérifiez que le corps de l'unité correspondante a déjà été élaboré. |
La vérification suivante correspond aux situations dans lesquelles l'exception STORAGE_ERROR est levée. Les seuls noms autorisés dans les pragmas correspondants sont les noms désignant des types d'accès, des unités de tâches ou des sous-programmes :
Vérification | Description |
---|---|
STORAGE_CHECK | Vérifiez que l'exécution d'un allocateur ne nécessite pas plus d'espace que celui disponible pour une collection. Vérifiez que l'espace disponible pour une tâche ou un sous-programme n'a pas été dépassé. |
Si une situation d'erreur survient en l'absence des contrôles d'exécution correspondants, l'exécution du programme est erronée (les résultats ne sont pas définis par le langage).
Exemples :
- pragma SUPPRESS(RANGE_CHECK);
- pragma SUPPRESS(INDEX_CHECK, ON => TABLE);
Remarques : Pour certaines implémentations, il peut être impossible ou trop coûteux de supprimer certains contrôles. Le pragma SUPPRESS correspondant peut être ignoré. Par conséquent, l'occurrence d'un tel pragma dans une unité donnée ne garantit pas que l'exception correspondante ne se produira pas ; les exceptions peuvent également être propagées par les unités appelées.