exponenta event banner

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

Аргумент std:: forward не должен использоваться впоследствии

Описание

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

Аргумент std:: forward впоследствии не используется.

Объяснение

Как правило, используется std::forward в шаблоне функции для передачи ссылочного параметра переадресации другой функции. Ресурсы параметра могут быть переданы другому объекту посредством операции перемещения в зависимости от категории значения параметра.

Для параметра rvalue параметр находится в неопределенном состоянии, если он перемещен из после вызова в std::forward и его не следует использовать повторно.

Для параметра lvalue при повторном использовании параметра после вызова std::forward, изменения параметра могут повлиять на аргумент вызывающей функции, которой передается параметр.

Внедрение Polyspace

Polyspace ® помечает вызов std::forward если переадресованный объект используется повторно после вызова. Polyspace также выделяет строки, в которых пересылаемый объект повторно используется в коде.

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

template<typename T>
void func(T&& t)
{
  T&& p = t;

  switch(t) { 
    case 0:
      p = std::forward<T>(t); 
      break;
    case 1:
      t--; //t reused 
      break;
  }
}

Поиск неисправностей

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

Примеры

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

#include <cstdint>
#include <iostream>
#include <utility>

namespace myTemplates
{

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

template<typename T>
void f2(T&& t2, bool b)
{
    if (b) {
        f1(std::forward<T>(t2)); // Compliant
    } else {
        t2++;  // else branch not entered
    }

}


template<typename T>
void f3(T&& t3)
{
    T&& p = std::forward<T>(t3); // Non-compliant

    switch (t3) {                // t3 reused
    case 0:
        t3++;                    // t3 reused
        break;
    case 1:
        t3--;                    // t3 reused
        break;
    default:
        break;
    }
}


template<typename T>
void f4(T&& t4)
{
    --t4;

    f1(std::forward<T>(t4)); // Non-compliant

    t4++;                    // t4 reused

    f1(std::forward<T>(t4)); // Non-compliant and t4 reused

    t4--;                    // t4 reused
}


template<typename T>
void f5(T&& t5)
{
    f1(t5,                   // t5 reused
       std::forward<T>(t5)); // Non-compliant
}

}

void main(void)
{
    int i;

    myTemplates::f2(i, true);
    myTemplates::f3(i);
    myTemplates::f4(i);
    myTemplates::f5(i);

}

В этом примере Polyspace помечает все вызовы std::forward где параметр переадресации используется повторно после вызова. В функции шаблона f4, второй вызов std::forward подсчитывает как повторное использование параметра t4. Нарушений этого правила в f2 потому что t2 повторно используется в else ветвь, которая никогда не вводится.

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

Группа: Библиотека поддержки языка
Категория: Обязательно, Автоматизировано
Представлен в R2020b