Почему не вызываются деструкторы обьектов при аппаратном исключении?
Есть вот такая программа, которая компилируется с разными моделями исключений под msvc x64.
#include <cstdio>
struct A
{
A(int order) : m_order(order){}
~A(){printf("~A(%d)\n", m_order);}
int m_order;
};
void foo(void)
{
A a = 2;
int i = 0;
int j = 10 / i;
}
void foo1()
{
A a = 1;
foo();
}
void main()
{
try
{
foo1();
}
catch (...)
{
}
}
Когда используется опция /EHa то имеем вот такой вывод:
~A(2)
~A(1)
Когда используется опция /EHsc то имеем пустой вывод.
Возникает вопрос, почему не вызываются деструкторы обьектов? Насколько я понимаю компилятор реализует с++ исключение используя windows реализацию seh. Я думал что это как раз позволит корректно делать раскрутку стэка в любой модели исключений. Получается чтобы исключить утечки памяти и прочее мне всегда нужно использовать /EHa модель? документация от microsoft как раз утверждает что необходимо использовать по возможности /EHsc но как тогда это обеспечит корректную очистку ресурсов в случае аппаратного исключения?
Ответы (1 шт):
При обработке SEH исключений действия по финализации осуществляются в блоке __finally, а не при раскрутке стека. Причем они работают и в С коде, где исключений и раскрутки стека нет. Опция /EHa включает раскрутку стека при обработке SEH исключений по аналогии с семантикой С++ исключений. А использовать вам нужно всегда /EHsc и не смешивать С++ объекты и С++ исключения с SEH исключениями (возникновение которых при работе обычной С++ программы говорит о наличии в ней ошибки).