6 Basic concepts [basic]

6.6 Start and termination [basic.start]

6.6.4 Termination [basic.start.term]

Destructors для инициализированных объектов (то есть объектов, которые lifetime были начаты) со статической продолжительностью хранения, и функции, зарегистрированные с помощью std​::​atexit, вызываются как часть вызова . Вызов выполняется до вызова деструкторов и зарегистрированных функций. [ Возврат из invokes ( ). ]std​::​exit std​::​exit Note: main std​::​exit [basic.start.main]end note

Деструкторы для инициализированных объектов с продолжительностью хранения потока в данном потоке вызываются в результате возврата из начальной функции этого потока и в результате вызова этого потока std​::​exit. Завершение деструкторов для всех инициализированных объектов с длительностью хранения потока в этом потоке строго происходит до инициирования деструкторов любого объекта со статической продолжительностью хранения.

Если завершение конструктора или динамическая инициализация объекта со статической продолжительностью хранения сильно происходит раньше, чем у другого, завершение деструктора второго упорядочивается до инициирования деструктора первого. Если завершение конструктора или динамическая инициализация объекта с продолжительностью хранения потока происходит раньше, чем у другого, завершение деструктора второго выполняется до запуска деструктора первого. Если объект инициализируется статически, он уничтожается в том же порядке, как если бы объект был инициализирован динамически. Для объекта типа массива или класса все подобъекты этого объекта уничтожаются до того, как будет уничтожен любой объект блочной области со статической продолжительностью хранения, инициализированный во время построения подобъектов. Если уничтожение объекта со статической продолжительностью хранения или продолжительностью хранения потока завершается через исключение, std​::​terminate вызывается.

Если функция содержит объект области видимости блока со статической продолжительностью хранения или продолжительностью хранения потока, который был уничтожен, и функция вызывается во время уничтожения объекта со статической продолжительностью хранения или продолжительностью хранения потока, программа имеет неопределенное поведение, если поток управления проходит через определение ранее уничтоженного объекта блочной области. Точно так же поведение не определено, если объект области видимости блока используется косвенно (т. Е. Через указатель) после его уничтожения.

Если завершение инициализации объекта со статической продолжительностью хранения происходит строго перед вызовом std​::​atexit (см. <cstdlib>, [support.start.term]), Вызов переданной функции std​::​atexit упорядочивается до вызова деструктора для объекта. Если вызов std​::​atexit строго происходит до завершения инициализации объекта со статической продолжительностью хранения, вызов деструктора для объекта упорядочивается до вызова переданной функции std​::​atexit. Если вызов std​::​atexit строго происходит перед другим вызовом std​::​atexit, вызов функции, переданной второму std​::​atexit вызову, упорядочивается до вызова функции, переданной первому std​::​atexit вызову.

Если в обработчиках сигналов ([support.runtime]) не разрешено использование объекта стандартной библиотеки или функции , которая не happen before завершает уничтожение объектов со статической продолжительностью хранения и выполнение std​::​atexit зарегистрированных функций ([support.start.term]), программа имеет неопределенное поведение. [ Note: Если есть использование объекта со статической продолжительностью хранения, которое не происходит до разрушения объекта, программа имеет неопределенное поведение. Завершение каждого потока перед вызовом std​::​exit или выходом из main него достаточно, но не обязательно, чтобы удовлетворить этим требованиям. Эти требования разрешают диспетчеры потоков как объекты статической продолжительности хранения. ] end note

Вызов функции, std​::​abort() объявленной в, <cstdlib> завершает программу без выполнения каких-либо деструкторов и без вызова функций, переданных в std​::​atexit() или std​::​at_­quick_­exit().