【问题标题】:Guard in c++, destructor not called when the exception is not treated in mainc++中的守卫,在main中不处理异常时不调用析构函数
【发布时间】:2016-08-12 00:13:47
【问题描述】:

如果我们用 g++ 或 clang 考虑下面的代码,至少在 main 函数中没有捕获到异常时,不会调用 Guard 类的析构函数。我做了一个谷歌搜索,没有找到任何有用的信息。

我在很多地方使用警卫类来实现 RAII。因此,我发现这非常令人失望,尤其是在处理信号量等资源时。

尽管 C++ 要求在抛出异常时调用析构函数。这是行为标准还是 libstdc++ 实现的原因?

感谢您在此问题上提供的任何帮助或建议。

#include<iostream>
#include<memory>

struct Guard
{
  Guard()
    : v(new int)
  {
    std::cout << "Guard()" << std::endl;
  }
  ~Guard(){
    std::cout << "~Guard()" << std::endl;
    delete v;
  }
private:
  int *v;
};

void test(){
  auto g = std::make_shared<Guard>();
  throw("youch");
}

void test2(){
  test();
}


int main(void){
  // try{
    test2(); 
  // } catch(...){

  // }
  return 0;
}

附: : 我不希望在主函数中添加 try/catch 块,因为我很高兴能够将异常追溯到调试器中发出的位置。

【问题讨论】:

    标签: c++ exception guard raii


    【解决方案1】:

    您正在处理实现定义的行为。根据标准 [except.handle]

    如果没有找到匹配的处理程序,则调用函数std::terminate();在此调用 std::terminate() 之前是否展开堆栈是实现定义的

    所以g 可能会也可能不会被销毁,具体取决于您使用的实现。您将无法依赖始终以相同的方式处理此问题。

    【讨论】:

    • 感谢您的准确回答。我必须说这种未定义的行为非常令人沮丧。事实上,我不知道必须设置一个异常处理程序来确保 RAII 在所有情况下都能正常工作。
    猜你喜欢
    • 2023-03-17
    • 2012-01-23
    • 2014-05-26
    • 1970-01-01
    • 2020-02-24
    • 2013-04-01
    • 2012-06-16
    • 1970-01-01
    • 2017-08-16
    相关资源
    最近更新 更多