Порядок между уничтожением глобального объекта и атаке в переполнении стека

Интересно, что может быть порядок между разрушением глобального объекта и 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 ().

14

Решение

ОБНОВИТЬ: 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 совместимы в этом отношении, как показано в этом живой пример.

14

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]