11.6 Exceptions and Optimization
clause gives permission to the implementation to perform certain “optimizations”
that do not necessarily preserve the canonical semantics.
The rest of this International
Standard (outside this clause) 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 with the
”, 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 clause.
The following additional
permissions are granted to the implementation:
implementation need not always raise an exception when a language-defined
check fails. Instead, the operation that failed the check can simply
yield an undefined result. The exception need 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 need 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 has no Inline pragma
applied to it. 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.
5 The permissions granted by this clause
can have an effect on the semantics of a program only if the program
fails a language-defined check.