程序在VS2017上以"abort() has been called"错误结束

Program ends with "abort() has been called" error on VS2017

本文关键字:been has called 结束 错误 VS2017 上以 abort 程序      更新时间:2023-10-16

下面的代码通过给出错误退出

"abort(( 已被调用"。

是由于析构函数抛出异常吗?我知道从析构函数中抛出异常会导致未定义的行为,但也有反驳。此外,相同的程序在VS 2012中工作正常。

#include "stdafx.h"
#include<iostream>
using namespace std;
class Txn
{
 public:
     Txn()
     {
        cout<< "in Constructor" << endl;
     };
    ~Txn()
    {
        try
        {
            cout << "in destructor" << endl;
            throw 10;
        }
        catch(int i)
        {
            cout << "in destructor exception" << endl;
            throw;
        }
    }
};
int main()
{
    try
    {
        Txn t;
    }
    catch (int i)
    {
        cout << "Exception" << i << endl;
    }
    return 0;
}

VS2017发行说明未提及有关异常处理更改的任何内容。

所以我有以下问题:

  1. 从VS2017开始在析构函数中抛出异常是否正确? 它会总是通过调用 abort(( 退出程序吗?
  2. 有没有任何标志可以让它工作?

请指教。

这里的问题是默认情况下所有析构函数都是noexcept(true)的。 抛出异常而不更改将立即调用std::terminate。 如果我们使用

class Txn
{
 public:
     Txn()
     {
        cout<< "in Constructor" << endl;
     };
    ~Txn() noexcept(false)
    {
        try
        {
            cout << "in destructor" << endl;
            throw 10;
        }
        catch(int i)
        {
            cout << "in destructor exception" << endl;
            throw;
        }
    }
};
int main()
{
    try
    {
        Txn t;
    }
    catch (int i)
    {
        cout << "Exception" << i << endl;
    }
    return 0;
}

程序按预期运行。


这在VS2012中有效但不适用于VS2017的原因是,在C++11之前,析构函数可以在无需指定的情况下抛出它。 使用 C++11 noexcept说明符以及默认情况下noexcept所有析构函数的更改会导致它在 VS2017 中中断。

默认情况下,

析构函数应不会抛出异常 ( noexcept (。您可以通过添加 noexcept(false) 来告诉编译器此析构函数未使用默认值。

在这个例子上尝试这样做时,我们现在从编译器那里得到一个不同的诊断 - 析构函数永远不会到达终点。析构函数永远不会完全销毁对象是不好的......

为了"修复"这个问题,我必须用if使重新抛出有条件。

class Txn
{
 public:
     Txn()
     {
        cout<< "in Constructor" << endl;
     };
    ~Txn() noexcept(false)
    {
        try
        {
            cout << "in destructor" << endl;
            throw 10;
        }
        catch(int i)
        {
            cout << "in destructor exception" << endl;
            if (i == 10) throw;
        }
    }
};

未定义的行为可以是任何东西,包括对 abort(( 的调用;只要避免一切可能诱发它的东西。

不禁止从析构函数抛出,但在 try/catch 中执行此操作可能会导致引发双重异常。

相关文章: