AUTOSAR C++14 Rule A15-3-4

Обработчики catch-all (ellipsis и std:: exception) должны использоваться только в (a) основных, (b) основных функциях задачи, (c) в функциях, которые должны изолировать независимые компоненты и (d) при вызове стороннего кода, который использует исключения не согласно рекомендациям AUTOSAR C++ 14

Описание

Определение правила

Обработчики catch-all (ellipsis и std:: exception) должны использоваться только в (a) основных, (b) основных функциях задачи, (c) в функциях, которые должны изолировать независимые компоненты и (d) при вызове стороннего кода, который использует исключения, не соответствующие рекомендациям AUTOSAR C++ 14.

Объяснение

Захватывайте все обработчики, такие как catch(std::exception) или catch(...) блоки соответствуют многим различным типам исключений. Если вы обрабатываете исключение при помощи такого обработчика catch-all, у вас нет подробной и конкретной информации о вызванном исключении. Такие обработчики catch-all не могут предпринять значимых действий, чтобы обработать вызванные исключения. Эти обработчики catch-all полезны при обработке неожиданных исключений, снова поднимая исключения или правильно выходя из приложения.

Поскольку обработчики catch-all полезны для определенных целей, их неэффективно использовать в каждой функции. Используйте обработчики catch-all в:

  • Основные функции

  • Основные функции задачи

  • Функции, которые вызывают стороннюю функцию, которая может быть несовместима с рекомендациями AUTOSAR C++ 14

  • Функции, которые предназначены для выделения независимых компонентов вашего кода

Реализация Polyspace

Polyspace® флаги catch(std::exception) и catch(...) блоки в функции, если ни одно из них не является true:

  • Функция является main() функция.

  • Функция является основной функцией задачи.

  • Функция вызывает внешнюю или стороннюю функцию, которая может выйти за исключением.

Polyspace обнаруживает main() функция. Чтобы задать функцию в качестве основной функции задачи, используйте следующие опции компиляции:

  • -entry-points < имя >

  • -циклические-задачи < имя >

  • -interrupts < имя >

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

Если вы ожидаете нарушения правил, но не видите его, обратитесь к разделу «Стандартные нарушения кодирования не отображаются».

Примеры

расширить все

В этом примере показано, как Polyspace флаги ловят-все обработчики в основной функции задачи EntryPoint и функцию, не являющуюся входной точкой NonEntryPoint(). Чтобы задать функцию EntryPoint в качестве основной функции задачи используйте опцию компиляции -entry-points EntryPoint.

#include <stdexcept>
#define MYEXCEPTION std::exception &
class ExceptionBased: std::exception {
};
typedef std::exception MyException;
typedef std::exception & MyExceptionRef;

void NonEntryPoint() 
{
	try {
		int i = 2;

		// ...
	} catch (int i) {                   // Compliant
	} catch (int &i) {                  // Compliant
	} catch (std::runtime_error e) {    // Compliant
	} catch (std::runtime_error& e) {   // Compliant
	} catch (std::exception *e) {       // Compliant
	} catch (std::exception e) {        // Noncompliant
	} catch (const std::exception& e) { // Noncompliant
	} catch(MyException e){             // Noncompliant
	} catch(ExceptionBased e){          // Compliant
	} catch (...) {                     // Noncompliant
	}
}
void EntryPoint() noexcept
{
	try {
		int i = 2;

		// ...
	} catch (MyException &e) {          // Compliant
	} catch (MyException e) {           // Compliant
	} catch (MyExceptionRef e) {        // Compliant
	} catch (ExceptionBased e) {        // Compliant
	} catch (const std::exception& e) { // Compliant
	} catch (MYEXCEPTION e) {           // Compliant
	}
}

Функция NonEntryPoint() не является main() или основной функцией задачи. В этой функции Polyspace помечает эти блоки catch-all:

  • The catch (std::exception e) блок соответствует различным типам исключений, происходящих из класса std::exception. Этот обработчик catch-all полезен в основной или основной функции задачи. Потому что NonEntryPoint() не является ни main() ни основная функция задачи, Polyspace помечает оператор catch (std::exception e). По этой же причине Polyspace помечает оператора catch (std::exception& e).

  • MyException является typedef от std::exception. The catch(MyException e) блок соответствует различным типам исключений, происходящих из класса std::except. Потому что NonEntryPoint() не является ни основной, ни основной функцией задачи, Polyspace помечает оператор catch(MyException e).

  • Потому что NonEntryPoint() не является ни основной, ни основной функцией задачи, Polyspace помечает оператор catch(...)

Функция EntryPoint() задается как основная функция задачи. Polyspace не помечает блоки catch-all в этой функции.

#include <stdexcept>
void Fextern_throw(void);
void Fextern_nothrow(void) noexcept(true);
void Foo0()
{
	try {
		Fextern_nothrow();
	} catch (...) {                 // Noncompliant
	}
}
void Foo1()
{
	try {
		try {
			Fextern_throw();
		} catch (...) {               // Compliant
		}
	} catch (std::exception& e) {   // Compliant
	}
}
void Foo2()
{
	try {
		try {
			Fextern_nothrow();
		} catch (...) {               // Noncompliant
			Fextern_throw();            
		}
	} catch (std::exception& e) {   // Compliant
	}
}
  • Функция Foo0() вызывает функцию стороннего производителя Fextern_nothrow(), который задается как noexcept(true). Поскольку код третьей стороны задан как noexcept, Polyspace помечает catch(...) блок в Foo0().

  • Функция Foo1() вызывает функцию стороннего производителя Fextern_throw() это может вызвать исключение. Поскольку сторонний код может вызвать исключение, Polyspace не помечает блоки обработчика catch-all в Foo1().

  • Функция Foo2() содержит вложенный try-catch блок. Во внутреннем блоке внешняя функция Fextern_nothrow() вызывается, который задается как noexcept(true). Polyspace помечает catch(...) блок во внутренней try-catch блок. Блок catch-all во внешней try-catch совместим, поскольку этот блок обрабатывает исключения, которые могут быть вызваны внешней функцией Fextern_throw().

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

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