Интересно, что может быть порядок между разрушением глобального объекта и atexit
в C ++
У меня есть глобальный объект и регистрация atexit
функция как ниже:
static MyClass g_class;
void onExit()
{
// do some destruction
}
int main()
{
atexit(onExit);
return 0;
}
я обнаружил onExit()
вызывается раньше MyClass::~MyClass()
в Visual Studio 2012 и gcc4.7.2. Я уверен, что onExit
всегда вызывается перед глобальным объектом (например, g_class
) уничтожение?
Интересно, глобальный порядок регистрации объектов и atexit
зарегистрировать заказ использовать ту же таблицу заказов.
Или нет никакой связи между глобальным порядком объектов и atexit
порядок?
Отредактировано: Извините, я написал ошибку. Я так растерялся, когда приводил пример кода. onExit()
вызывается до ~ MyClass ().
ОБНОВИТЬ: OP привел в замешательство, и кажется, что VC11 действительно ведет себя так, как указано в стандарте C ++ 11. Следующий ответ был написан в предположении, что это не так.
Поэтому ответ на этот вопрос:
Я уверен, что
onExit
всегда вызывается перед глобальным объектом (например,g_class
) уничтожение?
Является «Да», до тех пор, пока вы работаете с полностью совместимым компилятором.
я обнаружил
MyClass::~MyClass()
вызывается раньшеonExit()
в Visual Studio 2012.
Если это так, то это ошибка в VC11. Согласно пункту 3.6.3 / 1 стандарта C ++ 11:
Деструкторы (12.4) для инициализированных объектов (то есть объектов, время жизни которых (3.8) началось) со статической памятью
продолжительность называются в результате возвращения изmain
и в результате звонкаstd::exit
(18,5). […]
Кроме того, согласно пункту 3.6.3 / 3:
Если завершение инициализации объекта со статической длительностью хранения упорядочено перед вызовом
вstd::atexit
(увидеть<cstdlib>
18,5), вызов функции переданstd::atexit
последовательность перед вызовом деструктора для объекта.
Поэтому в вашем случае onexit()
должен быть вызван перед деструктором MyClass
,
Насколько я могу судить, Clang 3.2 и GCC 4.8.0 совместимы в этом отношении, как показано в этом живой пример.
Других решений пока нет …