Spec-Zone.ru › Ada 95
Справочник по Ada 95

7.6.1 Завершение и финализация

Этот подпункт определяет завершение и выход из выполнения конструкций и сущностей. Мастер — это выполнение конструкции, включающей финализацию локальных объектов после ее завершения (и после ожидания любых локальных задач — см. 9.3), но перед выходом. Другие конструкции и сущности покидают выполнение немедленно после завершения.

Динамические семантика

Выполнение конструкции или сущности считается завершенным, когда достигнут конец выполнения или когда передача управления (см. 5.1) приводит к его прерыванию. Завершение из-за достижения конца выполнения или из-за передачи управления exit_, return_, goto_ или requeue_statement или выбора terminate_alternative называется нормальным завершением. В противном случае завершение считается ненормальным — когда управление передается из конструкции из-за прерывания или возбуждения исключения.
После завершения выполнения конструкции или сущности она выходит, что означает, что выполнение продолжается со следующего действия, как определено для выполняемого выполнения. Выход из выполнения происходит немедленно после его завершения, за исключением случая мастера: выполнения task_body, block_statement, subprogram_body, entry_body или accept_statement. Мастер завершается после завершения и перед выходом.
Для финализации мастера сначала ожидаются зависимые задачи, как объяснено в 9.3. Затем каждый объект, уровень доступности которого совпадает с уровнем доступности мастера, финализируется, если объект был успешно инициализирован и по-прежнему существует. Эти действия выполняются независимо от того, покинул ли мастер выполнение, достигнув последней инструкции, или посредством передачи управления. Когда передача управления приводит к завершению выполнения, каждый включенный мастер финализируется в порядке, от самого внутреннего к самому внешнему.
Для финализации объекта:
  • Если объект имеет базовый тип, финализация не имеет эффекта;
  • Если объект имеет управляемый тип, вызывается процедура Finalize;
  • Если объект имеет защищенный тип, выполняются действия, определенные в 9.4;
  • Если объект имеет составной тип, то после выполнения вышеуказанных действий, если таковые имеются, каждый компонент объекта финализируется в произвольном порядке, за исключением следующих случаев: если объект имеет компонент с дискриминантом доступа, ограниченным выражением для каждого объекта, этот компонент финализируется до любого компонента, не имеющего таких дискриминантов; для объекта с несколькими компонентами с таким дискриминантом они финализируются в обратном порядке их component_declarationов.
Непосредственно перед тем, как экземпляр Unchecked_Deallocation освобождает хранилище объекта, объект финализируется. Если экземпляр Unchecked_Deallocation никогда не применяется к объекту, созданному allocatorом, объект по-прежнему будет существовать, когда завершится соответствующий мастер, и будет финализирован тогда.
Порядок, в котором финализация мастера выполняет финализацию объектов, следующий: объекты, созданные объявлениями в мастере, финализируются в обратном порядке их создания. Для объектов, которые были созданы allocatorами для типа доступа, у которого конечный предок объявлен в мастере, это правило применяется так, как будто каждый такой объект, который по-прежнему существует, был создан в произвольном порядке в первой точке замораживания (см. 13.14) типа конечного предка.
Цель инструкции присваивания финализируется перед копированием нового значения, как объяснено в 7.6.
Если object_name в object_renaming_declaration или фактический параметр для параметра in out формального параметра обобщения в generic_instantiation обозначает любую часть анонимного объекта, созданного вызовом функции, анонимный объект не финализируется до тех пор, пока к нему больше нет доступа через какое-либо имя. В противном случае анонимный объект, созданный вызовом функции или aggregateом, финализируется не позднее конца самого внутреннего окружающего declarative_item или statement; если это compound_statement, объект финализируется до начала выполнения любого statement внутри compound_statement.
Если передача управления или возбуждение исключения происходит до выполнения финализации анонимного объекта, анонимный объект финализируется как часть финализаций, которые должны быть выполнены для самого внутреннего окружающего мастера объекта.

Ограниченные (временные) ошибки

Вызов Finalize или Adjust, который происходит в рамках финализации объекта или присваивания, является ограниченной ошибкой для распространения исключений. Возможные последствия зависят от того, какое действие вызвало операцию Finalize или Adjust:
  • Для Finalize, вызванного в рамках assignment_statement, в этот момент генерируется Program_Error.
  • Для Adjust, вызванного в рамках инициализации управляемого объекта, другие предполагаемые корректировки могут или могут не быть выполнены, а затем возбуждается Program_Error. Во время его распространения финализация может быть или не быть применена к объектам, у которых Adjust не удался. Для Adjust, вызванного в рамках оператора присваивания, все другие предполагаемые корректировки выполняются, а затем возбуждается Program_Error.
  • Для Finalize, вызванного в рамках вызова Unchecked_Deallocation, все другие предполагаемые финализации выполняются, а затем возбуждается Program_Error.
  • Для Finalize, вызванного в рамках финализации анонимного объекта, созданного вызовом функции или aggregateом, все другие предполагаемые финализации выполняются, а затем возбуждается Program_Error.
  • Для Finalize, вызванного из-за достижения конца выполнения мастера, все другие финализации, связанные с мастером, выполняются, а Program_Error возбуждается сразу после выхода из мастера.
  • Для Finalize, вызванного передачей управления exit_, return_, goto_ или requeue_statement, Program_Error возбуждается не раньше, чем после финализации мастера, в котором произошло исключение, и не позже точки, в которой нормальное выполнение продолжилось бы. Все другие финализации, которые должны быть выполнены до этой точки, выполняются перед возбуждением Program_Error.
  • Для Finalize, вызванного передачей управления, которая обусловлена возбуждением исключения, все другие финализации, которые должны быть выполнены для того же мастера, выполняются; Program_Error возбуждается сразу после выхода из мастера.
  • Для Finalize, вызванного передачей управления из-за прерывания или выбора альтернативы завершения, исключение игнорируется; все другие предполагаемые финализации выполняются.
ПРИМЕЧАНИЯ
18 Правила раздела 10 подразумевают, что непосредственно перед завершением раздела применяются операции Finalize к управляемым объектам на уровне библиотеки (включая те, которые созданы allocatorами типов доступа на уровне библиотеки, за исключением тех, которые уже финализированы). Это происходит после ожидания завершения задач на уровне библиотеки.
19 Константа является константой только между ее инициализацией и финализацией. Инициализация и финализация могут изменять значение константы.
20 Прерывание откладывается во время определенных операций, связанных с управляемыми типами, как объяснено в 9.8. Эти правила предотвращают прерывание, из-за которого управляемый объект остается в неопределенном состоянии.
21 Процедура Finalize вызывается при финализации управляемого объекта, даже если Finalize был вызван ранее, явно или как часть присваивания; следовательно, если управляемый тип явно контролируется (подразумевая, что его примитив Finalize напрямую вызывается), или не является ограниченным (подразумевая, что присваивание разрешено), его процедура Finalize должна быть разработана таким образом, чтобы не наносить ущерба, если она применяется ко второму экземпляру объекта.


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API