Incorrect value forwarding

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

Описание

Этот дефект происходит когда:

  • Вы используете 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 потому что этот параметр является передающей ссылкой (введите T&&). Если t1 инициализируется lvalue, перемещение может привести к неожиданной модификации параметра. Точно так же Polyspace отмечает использование std::move в func_auto потому что объекты типа auto&& рассматриваются как передачу ссылок.

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

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

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