AUTOSAR C++14 Rule A12-8-3

Перемещенный - от объекта не буду получен доступ чтением

Описание

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

Перемещенный - от объекта не буду получен доступ чтением.

Объяснение

Поскольку содержимое исходного объекта обычно не задано после операции пересылки, небезопасно выполнить операции, которые получают доступ к содержимому исходного объекта после операции пересылки. Доступ к содержимому исходного объекта после операции пересылки может привести к нарушению целостности данных, неожиданному значению или недопустимому разыменованию указателя.

Операции, которые не делают предположений о состоянии объекта, не нарушают это правило.

Стандарт C++ указывает, что эти операции пересылки оставляют исходный объект в хорошо заданном состоянии после перемещения:

  • Переместите конструкцию, присвоение перемещения, преобразовав [1] конструкция перемещения, и преобразовав присвоение перемещения std::unique_ptr ввод

  • Переместите конструкцию, присвоение перемещения, преобразовав конструкцию перемещения, преобразовав присвоение перемещения std::shared_ptr ввод

  • Переместите присвоение конструкции и перемещения от std::unique_ptr из std::shared_ptr ввод

  • Переместите конструкцию, присвоение перемещения, преобразовав конструкцию перемещения, и преобразовав присвоение перемещения std::weak_ptr ввод

  • std::move() из std::basic_ios ввод

  • Переместите конструктора и присвоение перемещения std::basic_filebuf ввод

  • Переместите конструктора и присвоение перемещения std::thread ввод

  • Переместите конструктора и присвоение перемещения std: unique_lock ввод

  • Переместите конструктора и присвоение перемещения std::shared_lock ввод

  • Переместите конструктора и присвоение перемещения std::promise ввод

  • Переместите конструктора и присвоение перемещения std::future ввод

  • Переместите конструкцию, присвоение перемещения, преобразовав конструкцию перемещения, и преобразовав присвоение перемещения std::shared_future ввод

  • Переместите конструктора и присвоение перемещения std::packaged_task ввод

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

Реализация Polyspace

Polyspace® повышает флаг, если исходный объект читается после того, как его содержимое перемещено в целевой объект путем вызова std::move функционируйте явным образом. Polyspace не отмечает доступ к исходному объекту если:

  • Исходный объект явной операции пересылки имеет эти типы:

    • std::unique_ptr

    • std::shared_ptr

    • std::weak_ptr

    • std::basic_ios

    • std::basic_filebuf

    • std::thread

    • std::unique_lock

    • std::shared_lock

    • std::promise

    • std::future

    • std::shared_future

    • std::packaged_task

  • Операция пересылки выполняется неявно. Например, функциональный std::remove может получить доступ к исходному объекту после неявной операции пересылки. Polyspace не отмечает его. Лучшая практика состоит в том, чтобы избежать таких операций и использовать более безопасные альтернативы, которые предотвращают случайный доступ, такой как std::erase.

  • Исходный объект имеет встроенный базовый тип, такой как: int, enum, float'double', указатель, std::intptr_t, std::nullptr_t.

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

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

Примеры

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

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

#include<string>
#include<iostream>
void F1()
{
	std::string s1{"string"};
	std::string s2{std::move(s1)}; 
	// ...
	std::cout
	<<  // Noncompliant
	s1
	<< "\n";
}

void F2()
{
	std::unique_ptr<std::int32_t> ptr1 = std::make_unique<std::int32_t>(0);
	std::unique_ptr<std::int32_t> ptr2{std::move(ptr1)};
	std::cout << ptr1.get() << std::endl; // Compliant by exception
}
void g(std::string v)
{
	std::cout << v << std::endl; 
}

void F3()
{
	std::string s;
	for (unsigned i = 0; i < 10; ++i) {
		s.append(1, static_cast<char>('0' + i));  //Noncompliant 
		g(std::move(s));
	}
}
void F4()
{
	for (unsigned i = 0; i < 10; ++i) {
		std::string s(1, static_cast<char>('0' + i)); // Compliant
		g(std::move(s));  
	}
}

  • В функциональном F1, представьте в виде строки s1 явным образом перемещен в s2 путем вызова std::move. После операции пересылки функция пытается считать s1. Polyspace отмечает эту попытку чтения исходного объекта после явного перемещения.

  • В функциональном F2, уникальный указатель ptr1 явным образом перемещен в ptr2. Поскольку std::unique_ptr остается в заданном состоянии после перемещения, читая источник уникальный указатель после того, как явное перемещение будет совместимо с этим правилом.

  • В функциональном F3, строка s явным образом перемещен, и затем это читается std::string::append функция. Polyspace отмечает эту попытку чтения исходного объекта после явного перемещения.

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

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

Группа: Специальные функции членства
Категория: Необходимый, Частично автоматизированный
Введенный в R2021a

[1]  Конструктор преобразования является конструктором, который не объявляется со спецификатором explicit. Смотрите конструктора Преобразования.