11.4 Exception Handling
[When an exception occurrence is raised, normal program
execution is abandoned and control is transferred to an applicable
exception_handler,
if any.
To
handle an exception occurrence
is to respond to the exceptional event.
To
propagate
an exception occurrence is to raise it again in another context; that
is, to fail to respond to the exceptional event in the present context.]
Ramification: In other words, if the
execution of a given construct raises an exception, but does not handle
it, the exception is propagated to an enclosing execution (except in
the case of a
task_body).
Propagation involves re-raising the same exception
occurrence. For example, calling an entry of an uncallable task raises
Tasking_Error; this is not propagation.
Dynamic Semantics
Within a
given task, if the execution of construct
a is defined by this
International Standard to consist (in part) of the execution of construct
b, then while
b is executing, the execution of
a
is said to
dynamically enclose the execution of
b.
The
innermost dynamically enclosing execution of a given execution
is the dynamically enclosing execution that started most recently.
To be honest: If
the execution of
a dynamically encloses that of
b, then
we also say that the execution of
b is
included in the
execution of
a.
Ramification: Examples: The execution
of an
if_statement
dynamically encloses the evaluation of the
condition
after the
if (during that evaluation). (Recall that “execution”
includes both “elaboration” and “evaluation”,
as well as other executions.) The evaluation of a function call dynamically
encloses the execution of the
sequence_of_statements
of the function
body
(during that execution). Note that, due to recursion, several simultaneous
executions of the same construct can be occurring at once during the
execution of a particular task.
Dynamically enclosing is not defined across
task boundaries; a task's execution does not include the execution of
any other tasks.
Dynamically enclosing is only defined for executions
that are occurring at a given moment in time; if an
if_statement
is currently executing the
sequence_of_statements
after
then, then the evaluation of the
condition
is no longer dynamically enclosed by the execution of the
if_statement
(or anything else).
When
an exception occurrence is raised by the execution of a given construct,
the rest of the execution of that construct is
abandoned; that
is, any portions of the execution that have not yet taken place are not
performed. The construct is first completed, and then left, as explained
in
7.6.1. Then:
If the construct is a
task_body,
the exception does not propagate further;
Ramification: When an exception is raised
by the execution of a
task_body,
there is no dynamically enclosing execution, so the exception does not
propagate any further. If the exception occurred during the activation
of the task, then the activator raises Tasking_Error, as explained in
9.2, “
Task Execution
- Task Activation”, but we don't define that as propagation;
it's a special rule. Otherwise (the exception occurred during the execution
of the
handled_sequence_of_statements
of the task), the task silently disappears. Thus, abnormal termination
of tasks is not always considered to be an error.
Otherwise, the occurrence is
propagated to the innermost dynamically enclosing execution, which
means that the occurrence is raised again in that context.
To be honest: As
shorthands, we refer to the
propagation of an exception, and the
propagation by a construct, if the execution of the construct
propagates an exception occurrence.
Ramification: {
AI95-00318-02}
This “replacement” semantics implies that the handler can
do pretty much anything the abandoned sequence could do; for example,
in a function, the handler can execute a return statement that applies
to the function.
Ramification: The rules for exceptions
raised in library units, main subprograms and partitions follow from
the normal rules, plus the semantics of the environment task described
in Clause
10 (for example, the environment task
of a partition elaborates library units and calls the main subprogram).
If an exception is propagated by the main subprogram, it is propagated
to the environment task, which then terminates abnormally, causing the
partition to terminate abnormally. Although abnormal termination of tasks
is not necessarily an error, abnormal termination of a partition due
to an exception
is an error.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe