AUTOSAR C++14 Rule A8-4-4

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

Описание

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

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

Объяснение

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

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

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

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

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

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

  • Кортежи легче работать, потому что возвращенный кортеж можно удобно обработать при помощи std::tie на сайте вызова. The 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