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

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

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

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

Выполнение конструкции или сущности считается завершенным, когда достигнут конец выполнения или при передаче управления (см. 5.1) происходит его отказ. Завершение из-за достижения конца выполнения или из-за передачи управления оператором exit_statement, оператором возврата, оператором goto_statement или requeue_statement или выбора terminate_alternative является нормальным завершением. Завершение является аномальным в противном случае — когда управление передаётся из конструкции из-за прерывания или возбуждения исключения.
После завершения выполнения конструкции или сущности она покидается, что означает продолжение выполнения следующего действия, как определено для выполняемого действия. Выход из выполнения происходит немедленно после завершения, за исключением случая выполнения главной конструкции: тела, отличного от тела package_body; statement; или expression, function_call или range, которые не являются частью окружающего expression, function_call, range или simple_statement , кроме simple_return_statement. Термин главный сам по себе относится к выполнению главной конструкции. Главный объект финализируется после завершения и до выхода.
Для финализации главного объекта сначала ожидаются зависимые задачи, как описано в 9.3. Затем каждый объект, уровень доступности которого такой же, как у главного объекта, финализируется, если объект был успешно инициализирован и всё ещё существует. Эти действия выполняются независимо от того, покинут ли главный объект достижением последнего оператора или путём передачи управления.
Когда передача управления вызывает завершение выполнения, каждый включенный главный объект финализируется в порядке от внутреннего к внешнему.
Для финализации объекта:
  • Если полный тип объекта — это элементарный тип, финализация не имеет эффекта;
  • Если полный тип объекта — это помеченный тип, и метка объекта идентифицирует управляемый тип, вызывается процедура Finalize этого управляемого типа;
  • Если полный тип объекта — это защищённый тип, или если полный тип объекта — это помеченный тип, и метка объекта идентифицирует защищённый тип, выполняются действия, определённые в 9.4;
  • Если полный тип объекта — это составной тип, то после выполнения вышеперечисленных действий, если таковые имеются, каждый компонент объекта финализируется в произвольном порядке, за исключением следующих случаев: если объект имеет компонент с дискриминантом доступа, ограниченным выражением для каждого объекта, этот компонент финализируется до любых компонентов, не имеющих таких дискриминантов; для объекта с несколькими компонентами с таким дискриминантом они финализируются в обратном порядке их component_declarationов;
  • Если объект имеет корасширения (см. 3.10.2), каждое корасширение финализируется после объекта, чья дискриминанта доступа его обозначает.
Непосредственно перед тем, как экземпляр Unchecked_Deallocation освобождает память объекта, объект финализируется. Если экземпляр Unchecked_Deallocation никогда не применяется к объекту, созданному allocator, объект по-прежнему будет существовать, когда соответствующий главный объект завершит работу, и он будет финализирован тогда.
Финализация главного объекта выполняет финализацию объектов, созданных объявлениями в главном объекте, в обратном порядке их создания. После завершения финализации главного объекта объекты, финализированные в рамках его финализации, перестают существовать, а также любые типы и подтипы, определённые и созданные внутри главного объекта.
Каждый непроизводный тип доступа T имеет связанную коллекцию, которая является множеством объектов, созданных allocatorами T или типов, производных от T. Unchecked_Deallocation удаляет объект из его коллекции. Финализация коллекции состоит из финализации каждого объекта в коллекции в произвольном порядке.
  • Для именованного типа доступа — первая точка заморозки (см. 13.14) типа.
  • Для типа параметра доступа — вызов, содержащий allocator.
  • Для типа результата доступа — внутри главного вызова (см. 3.10.2).
  • Для любого другого анонимного типа доступа — первая точка заморозки самого внутреннего окружающего объявления.
Целевое значение assignment_statement финализируется перед копированием нового значения, как объяснено в 7.6.
Главный объект объекта — это главный объект, охватывающий его создание, уровень доступности которого (см. 3.10.2) равен уровню доступности объекта, за исключением случая анонимного объекта, представляющего результат агрегата aggregate или вызова функции. Если такой анонимный объект является частью результата вычисления выражения фактического параметра для явно алиасированного параметра вызова функции, главный объект объекта — самый внутренний главный объект, охватывающий вычисление агрегата aggregate или вызова функции, исключая сам агрегат aggregate или вызов функции. В противном случае, главный объект такого анонимного объекта — самый внутренний главный объект, охватывающий вычисление агрегата aggregate или вызова функции, что может быть и самим агрегатом aggregate или вызовом функции.
В случае expression, являющегося главным объектом, финализация любых (анонимных) объектов происходит после завершения оценки expression и всех использований объектов, до начала выполнения любой последующей конструкции.

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

Вызов Finalize или Adjust, выполняемый в рамках финализации объекта или присваивания, является ограниченной ошибкой, если распространяет исключение. Возможные последствия зависят от действия, вызвавшего операцию Finalize или Adjust:
  • Для Finalize, вызванной в рамках assignment_statement, в этот момент возбуждается Program_Error.
  • Для Adjust, вызванной в рамках операций присваивания, отличных от вызовов в рамках assignment_statement, некоторые из подлежащих выполнению корректировок могут быть выполнены, а затем возбуждается Program_Error. Во время его распространения финализация может быть применена к объектам, корректировка которых не удалась. Для Adjust, вызванной в рамках assignment_statement, выполняется любая другая подлежащая выполнению корректировка, а затем возбуждается Program_Error.
  • Для Finalize, вызванной в рамках вызова экземпляра Unchecked_Deallocation, выполняются любые другие подлежащие выполнению финализации, а затем возбуждается Program_Error.
  • Этот абзац был удалён.
  • Для Finalize, вызванной в результате достижения конца выполнения главного объекта, выполняются любые другие финализации, связанные с главным объектом, и Program_Error возбуждается сразу после выхода из главного объекта.
  • Для Finalize, вызванной передачей управления оператором exit_statement, оператором возврата, оператором goto_statement или requeue_statement, Program_Error возбуждается не ранее, чем после финализации главного объекта, когда произошло исключение, и не позднее момента, когда нормальное выполнение продолжилось бы. Любые другие финализации, подлежащие выполнению до этого момента, выполняются до возбуждения Program_Error.
  • Для Finalize, вызванной передачей управления, обусловленной возбуждением исключения, выполняются любые другие подлежащие выполнению финализации для того же главного объекта; Program_Error возбуждается сразу после выхода из главного объекта.
  • Для Finalize, вызванной передачей управления из-за прерывания или выбора альтернативы terminate, исключение игнорируется; выполняются любые другие подлежащие выполнению финализации.

Разрешения для реализации

Если выполнение аллокатора порождает исключение, любые части выделенного объекта, которые были успешно инициализированы, могут быть завершены как часть завершения самого внутреннего главного контейнера, окружающего аллокатор.
Реализация может завершать объекты, созданные аллокатороми для типа доступа, чья область памяти поддерживает подпулы (см. 13.11.4), как если бы объекты были созданы (в произвольном порядке) в момент, когда была разработана область памяти, а не в первый момент заморозки типа доступа.
ПРИМЕЧАНИЕ 1 Правила раздела 10 подразумевают, что непосредственно перед завершением раздела Finalize операции применяются к объектам, контролируемым на уровне библиотеки (включая те, которые созданы аллокатороми типов доступа на уровне библиотеки, за исключением тех, которые уже завершены). Это происходит после ожидания завершения задач на уровне библиотеки.
ПРИМЕЧАНИЕ 2 Константа является константой только между её инициализацией и завершением. Инициализация и завершение допускают изменение значения константы.
ПРИМЕЧАНИЕ 3 Прерывание откладывается во время определенных операций, связанных с контролируемыми типами, как объяснено в 9.8. Эти правила препятствуют тому, чтобы прерывание привело к тому, что контролируемый объект останется в неопределённом состоянии.
ПРИМЕЧАНИЕ 4 Процедура Finalize вызывается при завершении контролируемого объекта, даже если Finalize был вызван ранее, явно или как часть присваивания; следовательно, если контролируемый тип явно контролируется (что подразумевает, что его базовая Finalize операция непосредственно вызываема), или не ограничен (что подразумевает, что присваивание разрешено), его процедура Finalize идеально спроектирована так, чтобы не иметь негативного эффекта, если она применяется второй раз к тому же объекту.


Spec-Zone.ru

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