为什么硬件异常后对象不清除?

问题描述

我正在学习 C++ 中的异常模型。以下示例为我展示了有趣的结果

#include <cstdio>

struct A
{
    A(int order) : m_order(order){}
    ~A(){printf("~A(%d)\n",m_order);}
    int m_order;
};

void foo(void)
{
    A a2 = 2;
    int i = 0;
    int j = 10 / i;
}

void foo1()
{
    A a1 = 1;
    foo();
}

void main()
{
    try
    {
        foo1();
    }
    catch (...)
    {
    }       
}

程序的执行结果实际上取决于异常模型。

对于 /EHa,我们有输出

~A(2)
~A(1)

对于/EHsc,我们一无所有。

据我所知,msvc c++ 编译器在内部使用 SEH支持 c++ 异常。我认为即使在两个选项(a1,a2/EHa)的硬件异常的情况下,它也可以正确调用对象 /EHsc 的析构函数。但是这个例子让我很困惑。事实证明,在硬件异常的情况下,我应该始终使用 /EHa 选项来避免可能的内存泄漏和损坏?但是文档说我应该尽可能使用 /EHsc 选项。

解决方法

/EHa 的问题在于它不能保证捕获所有可能的问题,但它会带来大量开销。 /EHsc 效率更高,并且仍然可以捕获每个 throw

例如,MSVC++ 可能会使用 x87、SSE 或 AVX 指令执行 /0.0,并且产生的硬件异常可能会有所不同。我不知道 /EHa 什么时候会发现。