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

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_declarations;
  • Если объект имеет корасширения (см. 3.10.2), каждое корасширение финализируется после объекта, доступный дискриминант которого его обозначает.
Непосредственно перед тем, как экземпляр Unchecked_Deallocation высвобождает память объекта, объект финализируется. Если экземпляр Unchecked_Deallocation никогда не применяется к объекту, созданному allocator, объект по-прежнему будет существовать, когда соответствующий мастер завершит работу, и он будет финализирован тогда.
Финализация мастера выполняет финализацию объектов, созданных объявлениями в мастере, в обратном порядке их создания. После завершения финализации мастера объекты, финализированные в рамках его финализации, перестают существовать, так же как и любые типы и подтипы, определённые и созданные в рамках мастера.
Каждый непроизводный тип доступа T имеет связанную коллекцию, которая представляет собой множество объектов, созданных allocators типа 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 потерпел неудачу. Для 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), как если бы объекты были созданы (в произвольном порядке) в момент, когда был разработан пул памяти, а не в момент первого момента заморозки типа доступа.
ПРИМЕЧАНИЯ
18 Правила раздела 10 подразумевают, что непосредственно перед завершением разбиения операции Finalize применяются к управляемым объектам на уровне библиотеки (включая те, что созданы аллокаторами типов доступа на уровне библиотеки, за исключением уже завершенных). Это происходит после ожидания завершения задач на уровне библиотеки.
19 Константа является константой только между ее инициализацией и завершением. Инициализация и завершение могут изменить значение константы.
20 Прерывание откладывается во время определенных операций, связанных с управляемыми типами, как объяснено в 9.8. Эти правила предотвращают то, чтобы прерывание привело к тому, что управляемый объект остался в неопределенном состоянии.
21 Процедура Finalize вызывается при завершении управляемого объекта, даже если Finalize был вызван ранее, явно или в рамках присваивания; следовательно, если управляемый тип явно контролируется (что подразумевает, что его базовая операция Finalize может вызываться напрямую) или не ограничен (что подразумевает, что присваивание разрешено), его процедура Finalize должна быть разработана таким образом, чтобы не иметь вредных последствий, если она применяется во второй раз к одному и тому же объекту.


Spec-Zone.ru

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