exponenta event banner

Неверная переадресация значений

Переданный объект может быть неожиданно изменен

Описание

Этот дефект возникает в следующих случаях:

  • Вы используете std:move переадресация ссылки на функцию, включая объекты типа auto &&.

  • Вы используете std:forward для пересылки ссылки rvalue на функцию.

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

Polyspace ® не помечает использование std:move или std:forward если переадресация функции не выполняется. Например, в этом фрагменте кода не возникает никаких дефектов при использовании std:move со ссылкой на пересылку b2 и использование std:forward со ссылкой на переоценку b1.

template <typename T1, typename T2>
void func(T1& b1, T2&& b2)
{
    const T1& b10 = std::forward<B>(b1);
    const T2& b20 = std::forward<B>(b2);
    const T1& b11 = std::move(b1);
    const T2& b21 = std::move(b2);
}

Риск

Используя std:move при пересылке ссылок может привести к неожиданному изменению значения lvalue. Используя std:forward с rvalue ссылки возможны, но он подвержен ошибкам и может увеличить сложность кода.

Зафиксировать

  • При пересылке ссылки rvalue на функцию используйте std:move для приведения объекта к значению rvalue.

  • При пересылке ссылки на пересылку (или универсальной ссылки) в функцию используйте std:forward приведение объекта к значению rvalue тогда и только тогда, когда объект привязан к значению rvalue. Ссылка на пересылку может быть привязана к значению rvalue или lvalue. Объекты с типом auto && рассматриваются как ссылки на пересылку.

Примеры

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

#include <cstdint>
#include <string>
#include <utility>


class A
{
public:
    explicit A(std::string&& s)
        : str(std::move(s)) 
    {
    }

private:
    std::string str;
};

template <typename ...T>
void f1(T...t);



template <typename T1, typename T2>
void func(T1&& t1, T2& t2)
{
    f1(std::move(t1));            
    f1(std::forward<T1>(t1));     

    f1(std::forward<T2>(t2));     
    f1(std::move(t2));            
}

void func_auto(A& var)
{
    auto&& var1 = var;
    f1(std::move(var1));                    
    f1(std::forward<decltype(var1)>(var1)); 
}

void main()
{
    int32_t i;
    func(0, i);
}

В этом примере функция шаблона func пересылка параметров t1 и t2 функционировать f1. Polyspace помечает использование std::forward с t2 поскольку этот параметр является ссылкой rvalue (тип T&).

Polyspace также отмечает использование std::move с t1 поскольку этот параметр является ссылкой на пересылку (type T&&). Если t1 инициализируется с помощью lvalue, перемещение может привести к неожиданному изменению параметра. Аналогично, Polyspace помечает использование std::move в func_auto потому что объекты типа auto&& рассматриваются как ссылки на пересылку.

Для каждого дефекта предложенная коррекция показана на следующей строке.

Информация о результатах

Группа: Программирование
Язык: C++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: INCORRECT_VALUE_FORWARDING
Воздействие: Высокое
Представлен в R2020b