AUTOSAR C++14 Rule A15-5-1

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

Описание

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

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

Объяснение

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

  • Деструкторы и функции освобождения: Когда исключение повышено, компилятор вызывает деструкторы и функции освобождения, чтобы безопасно удалить объекты в стеке. Если деструктор или функция освобождения выходы за исключением в то время, компилятор отключает выполнение программы неправильно. В зависимости от программного обеспечения или оборудования, которое вы используете, аварийное завершение программы может привести к утечкам ресурсов и уязвимостям системы обеспечения безопасности. Чтобы предотвратить эти проблемы, избегайте деструкторов и функций deallocator, которые могут выйти за исключением. Деструкторами по умолчанию и deallocators является noexcept функции. Когда вы обеспечиваете пользовательский деструктор или функцию освобождения, задаете их как noexcept и обработайте все исключения в функции так, чтобы они не выходили за исключениями. Для полиморфной иерархии классов это правило применяется к деструкторам основы и всех производных классов.

  • Переместите конструкторов и переместите операторы присваивания: Если конструктор перемещения или оператор присваивания перемещения выйдут за исключением, нельзя гарантировать, что программа вернется к состоянию, которым это было перед операцией пересылки. Избегайте конструктора перемещения или оператора присваивания перемещения, который может выйти за исключением. Задайте эти функции как noexcept потому что стандартные библиотечные функции могут избежать операций пересылки, если они не объявляются как noexcept. Можно также объявить эти специальные функции членства как =default. Для получения дополнительной информации о том, когда можно объявить специальные функции членства как =default, смотрите AUTOSAR C++14 Rule A12-0-1.

  • Функции подкачки: Разработчики ожидают, что функция подкачки не выходит за исключением. Если функция подкачки выходы за исключением, стандартными алгоритмами библиотеки и операциями копии не может работать в вашем коде как ожидалось. Задайте функции подкачки как noexcept. Избегайте операций, которые могут выйти за исключением в функциях подкачки.

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

Реализация Polyspace

Polyspace® отмечает пользовательский деструктор, функцию освобождения, конструктора перемещения, оператор присваивания перемещения и функцию подкачки, если это может повысить исключение. Если функцию называют swap или Swap и берет ссылку в качестве входа, Polyspace считает его функцией подкачки.

Polyspace игнорирует функции, которые объявлены, но не заданы.

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

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

Примеры

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

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

#include <stdexcept>
class Compliant
{
public:
	//...
	~Compliant()  //Compliant                            
	{
		try {
			// ...
			throw std::runtime_error("Error"); 
		}
		catch (std::exception& e) {
		//...	
		}
	}
};

class Noncompliant
{
public:
	//...
	~Noncompliant() 
	{
		throw std::runtime_error("Error"); //Noncompliant    
	}
	static void operator delete(void* ptr, std::size_t sz) 
	{
		// ...
		throw std::runtime_error("Error");    // Noncompliant
	}
};
  • Деструктор Compliant повышает исключение при помощи throw оператор. Поскольку это исключение обработано в функции деструктора при помощи try-catch блок, ~Compliant() совместимо с этим правилом.

  • Деструктор Noncompliant также повышает исключение при помощи throw оператор. Поскольку это исключение не обработано в функции, деструктор ~Noncompliant() выходы за исключением. Polyspace отмечает этот throw оператор в деструкторе.

  • Функция освобождения Noncompliant::delete() не выполняет это правило, потому что оно не обрабатывает исключение, повышенное в функции. Polyspace отмечает throw оператор в функции.

Polyspace отмечает операторы перемещения или конструкторов перемещения если:

  • Они могут выйти за исключением

  • Они не заданы как noexcept

Рассмотрите этот код, где операции пересылки реализованы для двух классов.

#include <stdexcept>
class Compliant
{
	//...
public:
	Compliant(Compliant&& rhs) noexcept   //Compliant          
	{
		try {
			// ...
			throw std::runtime_error("Error");
		}
		catch (std::exception& e) {
			//...
		}
	}

	Compliant& operator=(Compliant&& rhs) noexcept //Compliant   
	{
		try {
			// ...
			throw std::runtime_error("Error");
		}
		catch (std::exception& e) {
			//...
		}
		return *this;
	}	
};

class Noncompliant
{
public:
	//...
	Noncompliant(Noncompliant&& rhs) //Noncompliant 
	{
		// ...
		throw std::runtime_error("Error");    //Noncompliant
	}
	Noncompliant& operator=(Noncompliant&& rhs) //Noncompliant
	{
		// ...
		throw std::runtime_error("Error");   //Noncompliant
		return *this;
	}

};

  • Оператор присваивания перемещения и конструктор перемещения класса Compliant заданы как noexcept и эти функции обрабатывают исключения, которые возникают в них. Конструктор перемещения и оператор присваивания перемещения Compliant совместимы с этим правилом.

  • Оператор присваивания перемещения и конструктор перемещения класса Noncompliant не заданы как noexcept. Polyspace отмечает объявление этих функций.

  • Оператор присваивания перемещения и конструктор перемещения класса Noncompliant содержите throw оператор, которые повышают исключения, не обрабатывая их в этих функциях. Polyspace отмечает их throw операторы.

Рассмотрите этот код, содержащий две функции подкачки.

#include <stdexcept>
namespace Compliant{
	class C1{};
	void Swap(C1& lhs, C1& rhs) noexcept   //Compliantt
	{
		// Implementation
	}
}
namespace Noncompliant{
	class C2{};
	void Swap( C2& lhs, C2& rhs ) noexcept(false) //Noncompliant
	{
		throw std::runtime_error( "Error" );   //Noncompliant
	}
}
  • Функциональный Compliant::Swap() задан как noexcept и не повышает исключение. Эта функция подкачки совместима с этим правилом.

  • Функциональный Noncompliant::Swap() задан как noexcept(false) и это выходит за исключением. Polyspace отмечает спецификацию исключения функции и throw оператор.

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

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