AUTOSAR C++14 Rule A8-4-4

Несколько выходных значений от функции должны быть возвращены как struct или кортеж.

Описание

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

Несколько выходных значений от функции должны быть возвращены как struct или кортеж.

Объяснение

В функции C++, return оператор может возвратить только значение, сохраненное в одной переменной. Но значения, сохраненные в любом количестве дополнительных переменных в осциллографе вызывающей стороны, могут быть изменены вызываемым, если вы передаете эти значения ссылкой, и затем изменяете их в теле вызываемого. Например, рассмотрите функциональный foo:

int foo(int x, int& y)
{
  int z;
  y = x*x;
  z = x*x*x;
  return z;
}

Функциональный foo эффективно возвращает два целочисленных значения: квадрат входного параметра x (возвращенный ссылкой) и куб входного параметра x (возвращенный копией при помощи return оператор). Одновременно использование обеих стратегий возвратить несколько результатов значений в сложный функциональный интерфейс и может сделать ваш код менее читаемым и удобным в сопровождении. Вместо этого храня все возвращаемые значения в одном struct или кортеже и возвращая его при помощи return оператор приводит к более простому, более объединенному интерфейсу.

return оператор, который имеет struct или кортеж, может потребовать дорогого копирования от одной ячейки памяти до другого. Большинство компиляторов поддерживает оптимизацию возвращаемого значения и может устранить эту дорогую копию, приводящую к исполняемому коду с мало ни к каким издержкам, сопоставленным с такими возвратами.

Чтобы помочь вам решить, использовать ли struct или кортеж, чтобы возвратить несколько значений, рассмотрите:

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

  • Кортежи легче работать с тем, потому что возвращенный кортеж может быть удобно обработан при помощи std::tie на сайте вызова. std::tie метод помещает элементы кортежа непосредственно в существующие локальные переменные в вызывающей стороне.

Примечание

Это правило также применяется к std::pair, который является специальным видом кортежа, который имеет точно два элемента.

Реализация Polyspace

Средство проверки отмечает объявление функции, которое удовлетворяет одному из этих двух условий:

  • Функция имеет непустой тип возврата и по крайней мере один непостоянный параметр ссылки

  • Функция имеет больше чем один непостоянный параметр ссылки

Указания и ограничения по применению:

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

  • Средство проверки не отмечает операторы, которые нарушают это правило.

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

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

Примеры

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

#include <tuple>


int Divide1(int dividend, // Noncompliant, remainder returned as reference parameter 
			int divisor, int& remainder)   
{
  remainder = dividend % divisor;
  return dividend / divisor;
}

// Compliant, quotient and remainder combined into a tuple
std::tuple<int, int> Divide2(int dividend, int divisor)  
{
  return std::make_tuple(dividend / divisor, dividend % divisor);
}

int main()
{
  int quotient, remainder;
  // store in local variables
  std::tie(quotient, remainder) = Divide2(26, 5); 
  return 0;
}

Функциональный Divide1 имеет частное как возвращаемое значение и остаток как непостоянный параметр ссылки. Наличие непустого возвращаемого значения и непостоянного параметра ссылки нарушает это правило кодирования.

Функциональный Divide2 комбинирует частное и остаток в кортеж и возвращает кортеж. Этот шаблон кода выполняет правило.

struct fraction {
  int quotient;
  int remainder;
} ;



int Divide1(int dividend, // Noncompliant, quotient and remainder returned as reference parameters
			int divisor, int& quotient, int& remainder)   
{
  quotient = dividend / divisor;
  remainder = dividend % divisor;
}

// Compliant, quotient and remainder combined into a struct
fraction Divide2(int dividend, int divisor)  
{
  fraction answer;
  answer.quotient = dividend / divisor;
  answer.remainder = dividend % divisor;
  return answer;
}

int main()
{
  fraction answer;
  answer = Divide2(26,5);
  return 0;
}

Функциональный Divide1 имеет и частное и остаток как непостоянные параметры ссылки. Наличие нескольких непостоянных параметров ссылки нарушает это правило кодирования

Функциональный Divide2 комбинирует частное и остаток в struct и возвращает struct. Этот шаблон кода выполняет правило.

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

Группа: операторы объявления
Категория: консультация, автоматизированная
Введенный в R2020b