AUTOSAR C++14 Rule A18-9-3

Перемещение std:: не должно использоваться на объектах, объявленных const или const &

Описание

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

Перемещение std:: не должно использоваться на объектах, объявленных const или const &.

Объяснение

Когда вы используете std::move() на объекте, он приведен в rvalue. Затем компилятор управляет ресурсами объекта, вызывая конструктор или оператор с ближайшим соответствующим списком параметров. Если вы звоните std::move() на const или const& type object, вызов возвращает const или const& type rvalue. Потому что перемещайте конструкторы и операторы не берут const аргумент типа, компилятор вызывает конструктор копирования или оператор вместо конструктора перемещения или оператора. Рассмотрим этот фрагмент кода, где a const объект копируется, когда можно ожидать перемещения после вызова на std::move().

class string{
	//...
public:
	string(const string& rhs);// copy contructor
	string(string&& rhs);     //move constructor
};

void print(string text) {
	cout<<text;
	//...
}

int main(){
	int const message = "Error";
	//..
	print(std::move(message))// the copy constructor is called
}
Тип возврата std::move(message) является rvalue const string&&. Между конструкторами перемещений и копий классов string, только конструктор копирования принимает const аргумент type. Компилятор вызывает конструктор копирования и копирует ресурсы message в text.

Потому что std::move() не перемещает const или const& введите объект, избегайте использования std::move() на const или const& объекты. Если вы намерены переместить ресурсы из объекта, не объявляйте его как const или const&.

Реализация Polyspace

Polyspace® флаги использования std::move() на:

  • Объекты, которые объявлены const или const&.

  • Объекты, которые преобразуются в const или const&.

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

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

Примеры

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

#include <cstdint>
#include <utility>
class A
{
	// Implementation
};
void F1(const int32_t &is_const, int32_t &is_non_const)
{
	const A a1{};
	int32_t target = 0;
	A a2 = a1;              // Compliant
	A a3 = std::move(a1);   // Noncompliant
	
	target = 
	std::move((const int32_t &)is_non_const);// Noncompliant
	target = 
	std::move(static_cast<const int32_t &>(is_non_const));// Noncompliant 
	target = 
	std::move(const_cast<int32_t &>(is_const));// Compliant
}
int main(){
	//...
}

  • Polyspace помечает использование std::move() с const a1 объекта. Компилятор вызывает конструктор копирования для копирования a1 на a3. Можно ожидать, что компилятор вызовет конструктор перемещения.

  • Polyspace также помечает использование std::move() с объектом is_non_const когда он приведен к const. После кастинга компилятор вызывает конструктор копирования для копирования is_non_const на target. Можно ожидать, что компилятор вызовет конструктор перемещения.

  • Polyspace не помечает использование std::move()с не- const объект, который является результатом литья const is_const объекта в не - const вводить при помощи const_cast. После литья, is_const больше не является const объект. Компилятор вызывает конструктор перемещения.

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

Группа: Библиотека языковой поддержки
Категория: Необходимый, Автоматизированный
Введенный в R2020a