AUTOSAR C++14 Rule A15-1-1

Только экземпляры типов вывели из станд.:: исключение должно быть выдано.

Описание

Управляйте определением

Только экземпляры типов вывели из станд.:: исключение должно быть выдано.

Объяснение

При повышении родовых объектов, когда исключения могут сделать код трудным считать и снова использовать. Рассмотрите этот код, где исключения повышены в двух различных try-catch блоки.

try{
	//..
	throw 1; // 1 means logic error;
}
catch(...){
	//...
}
//...
try{
	//...
	throw  std::logic_error{"Logic Error"};
}
catch(std::exception& e){
	//..
}
В первом блоке кода, причине или значении этого исключения не ясно. Неоднозначное исключение, такое как этот может сделать код трудным считать и снова использовать. Подобные типовые исключения могут также столкнуться за исключениями, повышенными в другом месте в коде, делая исключения более трудными обработать. Это управляет государствами, что такие родовые объекты не приемлемы как объекты исключения.

Во втором блоке кода, значении и причине исключения ясно передается путем повышения определенного и уникального типа объекта как исключение. Такой throw операторы также совпадают со стандартными соглашениями. Очевидно передача намерения разработчика, соответствование стандартным соглашениям и повышение уникального типа исключений делают код легким считать, изучить, и снова использовать.

Класс std::exception обеспечивает сопоставимый интерфейс, чтобы повысить уникальные исключения, соответствующие определенным ошибкам. Это - стандартное соглашение использовать этот интерфейс для повышения исключений. Чтобы сделать ваш код читаемым и допускающим повторное использование, повысьте объекты определенных типов, которые выведены из std::exception как исключение. Родовые объекты типа std::exception не может быть уникальным. Такие исключения нарушают это правило.

Реализация Polyspace

  • Polyspace® отмечает throw оператор, если тип повышенного объекта не является классом, который публично выведен из std::exception.

  • Если повышенный объект является частью иерархии наследования кратного, то Polyspace отмечает объект, если ни один из базовых классов не выводит публично из std::exception или если базовые классы не включают std::exception.

  • Если вы используете throw; оператор без аргумента в блоке выгоды, Polyspace не отмечает throw; оператор.

Поиск и устранение проблем

Если вы ожидаете нарушение правила, но не видите его, обратитесь к Кодированию Стандартных Нарушений, Не Отображенных.

Примеры

развернуть все

В этом примере показано, как Polyspace отмечает throw операторы, которые повышают объекты несовместимой иерархии классов.

#include <stdexcept>
#include <memory>

class ConventionalException : public std::logic_error{
public:
	using std::logic_error::logic_error;
};
class CustomException {};
class CustomException_derived : public CustomException {};
class PrivateDerived : private std::exception {};
class ProtectedDerived : protected std::exception {};
class MultipleInheritenceCompliant : 
	public ConventionalException, public CustomException {
public:
	MultipleInheritenceCompliant()
	: ConventionalException("Logic Error and Data Error") {
	}
};
class MultipleInheritenceNoncompliant :
	public ProtectedDerived, public CustomException {};

void Foo() {
	throw std::exception();   // Noncompliant 
	throw CustomException(); // Noncompliant
	throw CustomException_derived(); // Noncompliant 
	throw PrivateDerived();       // Noncompliant 
	throw ProtectedDerived();     // Noncompliant 
	throw MultipleInheritenceCompliant(); // Compliant
	throw MultipleInheritenceNoncompliant(); // Noncompliant
	throw ConventionalException{"Logic Error"};//Compliant
	throw std::make_shared<std::exception> // Noncompliant
	(std::logic_error("Logic Error")); 
}

  • Polyspace отмечает оператор throw std::exception() потому что это повышает типовой std::exception объект, который не может быть уникальным в вашем коде.

  • Polyspace отмечает оператор throw CustomException() потому что класс CustomException не выводит из std::exception. Polyspace отмечает оператор throw CustomException_derived() по той же причине.

  • Polyspace отмечает оператор throw PrivateDerived() потому что класс PrivateDerived выводит из std::exception конфиденциально. Вы не можете отловить это исключение при помощи catch(std::exception& e) блокируйтесь из-за частного наследования между std::exception и PrivateDerived. Polyspace отмечает оператор throw ProtectedDerived() по той же причине.

  • Polyspace отмечает оператор throw MultipleInheritenceNoncompliant() потому что класс MultipleInheritenceNoncompliant публично не выводит из std::exception.

  • Polyspace отмечает оператор throw std::make_shared<std::exception>(std::logic_error("Logic Error")) потому что этот оператор повышает std::shared_ptr возразите как исключение, которое не выводит из std::exception.

  • Polyspace не отмечает операторы throw MultipleInheritenceCompliant() и throw ConventionalException{"Logic Error"} потому что эти операторы повышают объекты классов, которые публично выведены из std::exception.

В этом примере показано, как Polyspace отмечает throw операторы в блоке выгоды.

#include <memory>
#include <stdexcept>
class MyException : public std::logic_error
{
public:
	using std::logic_error::logic_error;
	// Implementation
};
void catch_and_rethrow() {
	try {
		/* ... */
	}catch (std::exception e) {
		throw; // Compliant
		throw e; // Noncompliant		
	}catch (std::exception& e) {
		throw e; // Noncompliant
		throw;   // Compliant
	}catch (MyException& Error) {
		throw Error; // Compliant
	}
}
  • Пустой throw; операторы в блоках выгоды могут повысить различные типы исключений в зависимости от контекста во время выполнения. Поскольку Polyspace анализирует throw; операторы без любой зависящей от контекста информации во время выполнения, это не может определить какой объект пустой throw; оператор может повысить. Polyspace не делает флага throw; операторы в блоках выгоды.

  • Polyspace отмечает операторы throw e потому что они повышают std::exception объект e как исключение. Избегайте такого throw операторы в блоках выгоды, которые принимают ссылки на или экземпляры std::exception класс.

  • Polyspace не отмечает оператор throw Error потому что это повышает объект класса MyException это выводит из std::exception.

Проверяйте информацию

Группа: Обработка исключений
Категория: консультация, автоматизированная
Введенный в R2020b