exponenta event banner

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

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

Описание

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

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

Объяснение

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

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

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

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

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

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

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

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

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