#include <cstdlib>
#include <thread>
#include <chrono>
#include <iostream>
using namespace std;
using namespace std::literals;
struct A
{
int n_ = 0;
A(int n) : n_(n) { cout << "A:" << n_ << endl; }
~A() { cout << "~A:" << n_ << endl; }
};
A a1(1);
int main()
{
std::thread([]()
{
static A a2(2);
thread_local A a3(3);
std::this_thread::sleep_for(24h);
}).detach();
static A a4(4);
thread_local A a5(5);
std::this_thread::sleep_for(1s);
std::exit(0);
}
Мой компилятор clang 5.0
с -std=c++1z
.
Результат выглядит следующим образом:
A:1 A:2 A:4 A:5 A:3 ~A:5 ~A:2 ~A:4 ~A:1
Обратите внимание, что ~A:3
нет, что означает, что объект A a3
не был уничтожен.
Однако согласно cppref:
std::exit
вызывает нормальное завершение программы. Выполняется несколько этапов очистки:Деструкторы объектов с длительностью локального хранения потока ... гарантированно будут вызываться.
exit(0)
. - person xmllmx   schedule 28.03.2017exit()
(и IO должен быть очищен перед его вызовом). - person Synxis   schedule 28.03.2017std::basic_fstream
(например), потому что поведение очистки при уничтожении вызвано деструктором членаstd::basic_filebuf
. - person Justin Time - Reinstate Monica   schedule 28.03.2017exit
). - person Synxis   schedule 29.03.2017std::exit()
предназначен для нормального завершения программы (включая вызов кода очистки), пользователи должны иметь возможность безоговорочно предположить, что вызовstd::exit
имеет тот же результат, что и выход из областиmain()
, которая включает вызов всех ожидаемых деструкторов. Еслиexit()
не сможет вызвать деструкторы, которые, как ожидается, будут вызываться при выходе, это нарушит значительную часть кода, включая, например, все, что полагается на гарантиюbasic_fstream
, что он автоматически сам себя очищает при уничтожении. , без явного указания сделать это. - person Justin Time - Reinstate Monica   schedule 30.03.2017exit()
сделал эту работу. Возможно, в будущем стандарт изменится, иexit()
будет работать так, как вы сказали, аquick_exit()
возьмет на себя предыдущую работуexit()
. См. blogs.msdn.microsoft.com/oldnewthing/20120105-00. /?p=8683. Конечно, вы не должны вызыватьexit()
в отладке, чтобы вызывались все ваши деструкторы. - person Synxis   schedule 30.03.2017quick_exit()
будет использоваться достаточно часто для изменения такой величины. Тем не менее, он имеет такую же гарантию в отношении файлового ввода-вывода, что является определенным преимуществом. - person Justin Time - Reinstate Monica   schedule 31.03.2017