exponenta event banner

Правило AUTOSAR C++ 14 A15-3-4

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

Описание

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

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

Объяснение

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

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

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

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

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

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

Внедрение Polyspace

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

  • Функция - main() функция.

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

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

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

  • -entry-points < имя >

  • -cyclic-задачи < имя >

  • -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:

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

  • MyException является typedef из std::exception. 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 блок. Улавливающий блок во внешнем try-catch совместим, поскольку этот блок обрабатывает исключения, которые могут быть вызваны внешней функцией Fextern_throw().

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

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