Программа заканчивается сообщением об ошибке abort() на VS2017

Ниже код выходит из-за ошибки

msgstr "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. Есть ли флаги, с которыми мы можем заставить его работать?

Пожалуйста, предложите.

3 ответа

Проблема здесь в том, что все деструкторы по умолчанию 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 деструктор мог выдавать без необходимости его указания. С С ++ 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 может привести к двойному исключению.

Другие вопросы по тегам