exponenta event banner

Правило AUTOSAR C++ 14 A18-9-3

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

Описание

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

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

Объяснение

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