The purpose of this section is to specify the conditions under which an implementation is allowed to perform certain actions either earlier or later than specified by other rules of the language.
In general, when the language rules specify an order for certain actions (the canonical order), an implementation may only use an alternative order if it can guarantee that the effect of the program is not changed by the reordering. In particular, no exception should arise for the execution of the reordered program if none arises for the execution of the program in the canonical order. When, on the other hand, the order of certain actions is not defined by the language, any order can be used by the implementation. (For example, the arguments of a predefined operator can be evaluated in any order since the rules given in section 4.5 do not require a specific order of evaluation.)
Additional freedom is left to an implementation for reordering actions involving predefined operations that are either predefined operators or basic operations other than assignments. This freedom is left, as defined below, even in the case where the execution of these predefined operations may propagate a (predefined) exception:
A preedefined operation need not be invoked at all, if its only possible effect is to propagate a predefined exception. Similarly, a predefined operation need not be invoked if the removal of subsequent operations by the above rule renders this invocation ineffective.
Rule (b) applies to predefined operators but not to the short-circuit control forms.
The expression SPEED < 300_000.0 can be replaced by TRUE if the value 300_000.0 lies outside the base type of SPEED, even though the implicit conversion of the numeric literal would raise the exception NUMERIC_ERROR.
declare N : INTEGER; begin N := 0; -- (1) for J in 1 .. 10 loop N := N + J**A(K); -- A and K are global variables end loop; PUT(N); exception when others => PUT("Some error arose"); PUT(N); end;
The evaluation of A(K) may be performed before the loop, and possibly immediately before the assignment statement (1) even if this evaluation can raise an exception. Consequently, within the exception handler, the value of N is either the undefined initial value or a value later assigned. On the other hand, the evaluation of A(K) cannot be moved before begin since an exception would then be handled by a different handler. For this reason, the initialization of N in the declaration itself would exclude the possibility of having an undefined initial value of N in the handler.
References: accept statement, accuracy of real operations, assignment, base type, basic operation, conversion, error situation, exception, exception handler, frame, numeric_error exception, predefined operator, predefined subprogram, propagation of an exception, real type, undefined value.