11.6 Exceptions and Optimization
This
subclause gives permission to the implementation to perform certain “optimizations”
that do not necessarily preserve the canonical semantics.
Dynamic Semantics
The rest of this Reference Manual
(outside this subclause) defines the
canonical semantics of the
language. The canonical semantics of a given (legal) program determines
a set of possible external effects that can result from the execution
of the program with given inputs.
As explained in
1.1.3,
“
Conformity of an Implementation”,
the external effect of a program is defined in terms of its interactions
with its external environment. Hence, the implementation can perform
any internal actions whatsoever, in any order or in parallel, so long
as the external effect of the execution of the program is one that is
allowed by the canonical semantics, or by the rules of this subclause.
Implementation Permissions
The following additional
permissions are granted to the implementation:
An implementation
can omit raising an exception when a language-defined check fails. Instead,
the operation that failed the check can simply yield an
undefined
result. The exception is required to be raised by the implementation
only if, in the absence of raising it, the value of this undefined result
would have some effect on the external interactions of the program. In
determining this, the implementation shall not presume that an undefined
result has a value that belongs to its subtype, nor even to the base
range of its type, if scalar. Having removed the raise of the exception,
the canonical semantics will in general allow the implementation to omit
the code for the check, and some or all of the operation itself.
If an exception is raised due
to the failure of a language-defined check, then upon reaching the corresponding
exception_handler
(or the termination of the task, if none), the external interactions
that have occurred have to reflect only that the exception was raised
somewhere within the execution of the
sequence_of_statements
with the handler (or the
task_body),
possibly earlier (or later if the interactions are independent of the
result of the checked operation) than that defined by the canonical semantics,
but not within the execution of some abort-deferred operation or
independent
subprogram that does not dynamically enclose the execution of the construct
whose check failed.
An independent subprogram is
one that is defined outside the library unit containing the construct
whose check failed, and for which the Inline aspect is False.
Any
assignment that occurred outside of such abort-deferred operations or
independent subprograms can be disrupted by the raising of the exception,
causing the object or its parts to become abnormal, and certain subsequent
uses of the object to be erroneous, as explained in
13.9.1.
NOTE The permissions granted by this
subclause can have an effect on the semantics of a program only if the
program fails a language-defined check.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe