Почему не вызываются деструкторы обьектов при аппаратном исключении?

Есть вот такая программа, которая компилируется с разными моделями исключений под 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 шт):

Автор решения: user7860670

При обработке SEH исключений действия по финализации осуществляются в блоке __finally, а не при раскрутке стека. Причем они работают и в С коде, где исключений и раскрутки стека нет. Опция /EHa включает раскрутку стека при обработке SEH исключений по аналогии с семантикой С++ исключений. А использовать вам нужно всегда /EHsc и не смешивать С++ объекты и С++ исключения с SEH исключениями (возникновение которых при работе обычной С++ программы говорит о наличии в ней ошибки).

→ Ссылка