Исключения и оптимизация
В данном разделе описаны условия, при которых в реализации можно выполнять те или иные действия раньше или позже, чем это определено правилами языка.
В целом, если правила языка задают порядок некоторых действий
[канонический порядок},
реализация может использовать альтернативный порядок при гарантии, что такое переупорядочивание не скажется на результате выполнения программы. В частности, если при выполнении программы в каноническом порядке не возбуждается никакое исключение, то также никакие исключения не должны возбуждаться при выполнении переупорядоченной программы. С другой стороны, если порядок некоторых действий не определен языком, то реализация может использовать любой порядок. (Например, аргументы предопределенной операции могут вычисляться в любом порядке, так как правила из разд. 4.5 не требуют определенного порядка выполнения.)
Реализации предоставляется дополнительная свобода для переупорядочивания действий, включающих предопределенные или базовые операции, за исключением присваивания. Эта свобода предоставляется даже в том случае, если при выполнении предопределенных операций может распространяться (предопределенное) исключение^ с учетом следующих правил:
а) С целью установления, одинаков ли результат выполнения некоторых действий в каноническом или альтернативном порядке, можно предположить, что ни одна из вызванных этими действиями предопределенных операций не распространяет (предопределенные) исключения, и при этом выполняются два следующих требования к реализации альтернативного порядка: во-первых, операция не должна вызываться в альтернативном порядке, если она не вызывается в каноническом порядке; во-вторых, самое внутреннее объемлющее окружение или оператор принятия для каждой операции должны быть одинаковы для канонического и альтернативного порядков с теми же самыми обработчиками исключений.
б) Связь знака операций с операндами в выражении определена синтаксисом. Однако для последовательности предопределенных операций с одним и тем же приоритетом (при отсутствии скобок, вводящих особые связи) эти связи могут быть изменены (и это допускается) при выполнении следующего требования: результат целого типа должен быть эквивалентен результату вычислений в каноническом порядке слева направо; результат вещественного типа должен принадлежать модельному интервалу результата, полученного после выполнения в каноническом порядке слева направо (см. 4.5.7).
Такое переупорядочивание допустимо даже тогда, когда может быть устранено некоторое исключение или вставлено предопределенное исключение.
Также дополнительная свобода предоставляется реализации при вычислении простых числовых выражений. При выполнении предопределенных операций в реализации допускается использование операций над типами, которые имеют более широкий диапазон результата, чем базовый тип операндов, при условии, что это приводит к точному результату (или результату с заданной точностью для вещественного типа), даже если промежуточные результаты выходят за границы базового типа. В таком случае нет необходимости возбуждать исключение NUMERIC_ERROR. В частности, если числовое выражение является операндом предопределенной операции отношения и может быть получен правильный результат типа BOOLEAN, то в процессе вычисления можно не возбуждать исключение NUMERIC_ERROR.
Нет необходимости в выполнении предопределенной операции, если ее единственным возможным результатом является распространение предопределенного исключения или если изменение последовательности операций по описаным выше правилам приводит к ее безрезультатному выполнению.
Примечание.
Правило б) применимо к предопределенным операциям, но неприменимо к формам управления с промежуточной проверкой.
Выражение SPEED < 300-000.0 может быть заменено на TRUE, если значение 300-000.0 находится вне границ базового типа для SPEED, даже если неявное преобразование этого числового литерала может возбудить исключение NUMERIC_ERROR.
Пример:
declare
N : INTEGER; begin
N := О; -- (1) for J in 1 .. 10 loop
N := N + J**A(K); -— А и К являются глобальными переменными end loop;
PUT(N); exception
when others => PUT("Some error arose"); PUT(N); end:
Вычисление А(К) может быть выполнено до цикла и, возможно, непосредственно перед оператором присваивания (1), даже если в нем может возбуждаться исключение. Следовательно, внутри обработчика исключения значение N будет либо неопределенным, либо результатом последнего присваивания.
С другой стороны, вычисление А(К) не может быть выполнено до
begin,
поскольку в этом случае исключение будет обрабатываться другим обработчиком. По этой причине инициализация N в описании будет исключать возможность наличия неопределенного начального значения N в обработчике.
Ссылки:
базовая операция типа 3.3.3, базовый тип 3.3, вещественный тип 3.5.6, исключение 11, исключение NUMERIC_ERROR 11.1, неопределенное значение 3.2.1, обработчик исключения 11.2, окружение 11.1, оператор принятия 9.5, ошибочная ситуация 11, присваивание 5.2, предопределенная операция 4.5, предопределенная подпрограмма 8.6, преобразование 4.6, распространение исключения 11.4, точность вещественных операций типа 4.5.7.
Пред. | Уровень выше | След. |
11.5. ИСКЛЮЧЕНИЯ, ВОЗБУЖДАЕМЫЕ ПРИ ВЗАИМОДЕЙСТВИИ ЗАДАЧ |
Содержание | 11.7. ПОДАВЛЕНИЕ ПРОВЕРОК |