【问题标题】:Why are objects not cleared after hardware exception?为什么硬件异常后没有清除对象?
【发布时间】:2021-08-08 14:52:07
【问题描述】:

我正在学习 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++ 异常。我认为即使在两个选项(/EHa/EHsc)出现硬件异常的情况下,它也将允许正确调用对象a1,a2 的析构函数。但是这个例子让我很困惑。事实证明,在硬件异常的情况下,我应该始终使用 /EHa 选项来避免可能的内存泄漏和损坏?但是文档说我应该尽可能使用/EHsc 选项。

【问题讨论】:

  • /EHa 是一个非常昂贵的标志,因为它阻止了许多优化,例如消除死存储。任何内存访问都可能导致硬件异常,因此您必须在每次内存访问之前溢出。通常,您应该只编写代码,以免发生硬件异常。 (或者更准确地说,假设任何硬件异常都是致命的。)C++ 语言本身并不要求编译器支持硬件异常的展开。

标签: c++ windows exception seh


【解决方案1】:

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

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

【讨论】:

  • 但是上面的例子表明 /Ehsc 不会在硬件异常的情况下销毁分配在堆栈上的对象
  • @LmTinyToon:没错。但是/EHa 也不保证。所以建议将/0 视为一个错误,并修复它。
猜你喜欢
  • 2013-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-10
相关资源
最近更新 更多