AUTOSAR C++14 Rule A15-4-3

noexcept спецификация функции должна или быть идентичной через все модули перевода, или идентичной или более строгой между виртуальной функцией членства и сверхнаездником

Описание

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

noexcept спецификация функции должна или быть идентичной через все модули перевода, или идентичной или более строгой между виртуальной функцией членства и сверхнаездником.

Объяснение

Модули перевода являются файлами другого источника, которые компилирует компилятор. Когда функция имеет различную спецификацию исключения в файлах другого источника, она может привести к неопределенному поведению. Точно так же различная спецификация исключения полиморфной функции в разных уровнях иерархии классов может привести к отказу компиляции в некоторых случаях. В зависимости от программного и аппаратного обеспечения, которое вы используете, различные технические требования исключения функции в различных местах могут вызвать отказ компиляции или привести к неопределенному продвижению поведения к уязвимостям системы обеспечения безопасности.

Избегать неопределенного поведения и уязвимостей системы обеспечения безопасности:

  • Сохраните ту же спецификацию исключения во всех объявлениях функции.

  • Если виртуальная функция объявляется при помощи noexcept или noexcept(true) как спецификация исключения, объявите функции сверхнаездника в производных классах при помощи той же спецификации.

  • Если виртуальная функция объявляется при помощи noexcept(false) как спецификация исключения, объявите функции сверхнаездника в производных классах при помощи любого noexcept(false) или noexcept(true) как спецификация исключения.

Реализация Polyspace

Polyspace® отмечает спецификацию исключения функции, если функция объявляется с различными техническими требованиями исключения в различных местах в файле. Polyspace отмечает функцию сверхнаездника в производном классе, если он задан как noexcept(fale) в то время как виртуальная функция в базовом классе задана как noexcept.

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

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

Примеры

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

В этом примере показано, как Polyspace отмечает объявления одной функции, которая имеет различные технические требования исключения. В одном файле file1.cpp, функции членства классов A и B объявляются.

//file1.cpp
class A
{
public:
	void F() noexcept;
	void G() noexcept(false);
	
};
class B
{
public:
	void W() noexcept;
	void R() noexcept(false);
	
};

В другом файле file2.cpp, функции членства этих классов заданы.

// file2.cpp
#include"file1.cpp"

void A::F() noexcept(false) //Noncompliant
{
	// Implementation
}
void A::G() noexcept //Noncompliant
{
	// Implementation
}


void B::W() noexcept //Compliant
{
	// Implementation
}
void B::R() noexcept(false) //Compliant
{
	// Implementation
}

Чтобы видеть нарушения этого правила, запустите Polyspace и задать оба file1.cpp и file2.cpp как исходные файлы при помощи опции -sources. Сохраните file1.cpp и file2.cpp в той же папке. Смотрите -sources для получения дополнительной информации об определении нескольких исходных файлов.

Компиляция может перестать работать, но Polyspace отмечает функции с помощью неидентичной спецификации исключения.

  • Функциональный A::F() объявляется infile1.cpp при помощи спецификации исключения noexcept, но это объявляется при помощи спецификации исключения noexcept(false) в file2.cpp. Polyspace отмечает неидентичную спецификацию исключения в последнем объявлении. По той же причине, спецификации исключения A::G() в file2.cpp также отмечается.

  • Функции B::W() и B::R() объявлены и заданы при помощи той же спецификации исключения в этих двух исходных файлах. Эти функции совместимы с этим правилом.

В этом примере показано, как Polyspace отмечает объявление функций сверхнаездника, которые имеют менее строгие технические требования исключения.

class A
{
public:
	virtual void V1() noexcept = 0;
	virtual void V2() noexcept(false) = 0;
	virtual void V3() noexcept = 0;
};
class B : public A
{
public:
	void V1() noexcept(false) override //Noncompliant
	{
		// Implementation
	}
	void V2() noexcept override //Compliant
	{
		// Implementation
	}
	void V3() noexcept override //Compliant
	{
		// Implementation
	}
};

Чистые виртуальные функции A::V1(), A::V2(), и A::V3() реализованы переопределяющими функциями B::V1(), B::V2(), и B::V3() соответственно.

  • Polyspace отмечает функциональный B::V1() потому что эта переопределяющая функция задана при помощи менее строгой спецификации исключения noexcept(false) по сравнению с виртуальной функцией базового класса A::V1(), который задан при помощи noexcept.

  • Polyspace не делает флага B::V2() потому что эта переопределяющая функция задана при помощи более строгой спецификации noexcept по сравнению с виртуальной функцией базового класса A::V2(), который задан при помощи noexcept(false).

  • Polyspace не делает флага B::V3() потому что эта переопределяющая функция задана при помощи той же спецификации исключения как виртуальная функция базового класса A::V3().

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

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