# V2539. MISRA. Class destructor should not exit with an exception.

Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.

Это правило справедливо только для C++. Бросание исключения в деструкторе объекта - плохая практика. Начиная с C++11, бросание исключения в теле деструктора приводит к вызову функции 'std::terminate'. Из этого следует, что исключение, брошенное внутри деструктора, должно быть обработано внутри того же деструктора.

Рассмотрим первый пример:

    LocalStorage::~LocalStorage()
    {
      ...
      if (!FooFree(m_index))
        throw Err("FooFree", GetLastError());
      ...
    }

Анализатор обнаружил деструктор, содержащий оператор throw вне блока try..catch. Данный код следует переписать таким образом, чтобы сообщить об ошибке, возникшей в деструкторе без использования механизма исключений. Если ошибка не критична, то ее можно игнорировать:

    LocalStorage::~LocalStorage()
    {
      try {
        ...
        if (!FooFree(m_index))
          throw Err("FooFree", GetLastError());
        ...
      }
      catch (...)
      {
        assert(false);
      }
    }

Также исключения могут возникать при вызове оператора 'new'. При невозможности выделения памяти будет сгенерировано исключение 'std::bad_alloc'. Рассмотрим второй пример:

    A::~A()
    {
      ...
      int *localPointer = new int[MAX_SIZE];
      ...
    }

Появление исключения также возможно и при использовании dynamic_cast<Type> при работе с ссылками. При невозможности приведения типов будет сгенерировано исключение 'std::bad_cast'. Рассмотрим третий пример:

    B::~B()
    {
      ...
      UserType &type = dynamic_cast<UserType&>(baseType);
      ...
    }

Для исправления данных ошибок следует переписать код таким образом, чтобы 'new' или 'dynamic_cast' были помещены в блок 'try-catch'.

Данная диагностика классифицируется как:

MISRA-CPP-2008-15.5.1