11.6 Exceptions and Optimization
This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue
[ This subclause gives permission to the implementation to perform certain “optimizations” that do not necessarily preserve the canonical semantics.]
Dynamic Semantics
2/3The 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
4The 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 X * Y > Integer'Last then
Put_Line("X * Y overflowed");
end if;
exception
when others =>
Put_Line("X * Y overflowed");
subtype Str10 is String(1..10);
type P10 is access Str10;
X : P10 := null;
begin
if X.all'Last = 10 then
Put_Line("Oops");
end if;
- 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 thesequence_of_statements
with the handler (or thetask_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.
Wording Changes from Ada 83
- Paragraphs 1 and 2 contain no semantics; they are merely pointing out that anything goes if the canonical semantics is preserved. We have similar introductory paragraphs, but we have tried to clarify that these are not granting any “extra” permission beyond what the rest of the document allows.
- Paragraphs 3 and 4 are reflected in the “extra permission to reorder actions”. Note that this permission now allows the reordering of assignments in many cases.
- Paragraph 5 is moved to 4.5, “Operators and Expression Evaluation”, where operator association is discussed. Hence, this is no longer an “extra permission” but is part of the canonical semantics.
- Paragraph 6 now follows from the general permission to store out-of-range values for unconstrained subtypes. Note that the parameters and results of all the predefined operators of a type are of the unconstrained subtype of the type.
- Paragraph 7 is reflected in the “extra permission to avoid raising exceptions”.