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'.
Данная диагностика классифицируется как:
|