Функции возвращают крупносерийный выходной параметр значением вместо ссылкой или указателем
Этот дефект происходит, когда функции возвращают объекты крупносерийного производства значением вместо объекта, возвращаемого ссылкой или указателем.
Это средство проверки повышено, если оба из этих условий верны:
Адрес возвращенного объекта остается допустимым после return
оператор.
Возвращенный объект является любым из них:
Нетривиально copyable объект. Возврат такого объекта значением может потребовать внешнего вызова функции, который является более дорогим, чем возврат его ссылкой. Чтобы проверять, copyable ли объект нетривиально, используйте функциональный std::is_trivially_copyable
. Для получения дополнительной информации об этой функции, смотрите std::is_trivially_copyable
в ссылке C++.
Большой тривиально copyable объект. Возврат тривиально copyable объекта значением является более дорогим, когда объект является большим.
Этот дефект не повышен, если возвращенный объект:
Недорогой, чтобы скопировать.
Временный объект или нестатический локальный объект.
Это неэффективно, чтобы возвратить большой объект значением, когда можно возвратить объект ссылкой или указателем. Функции могут непреднамеренно возвратить большой объект значением из-за недостающего &
или *
. Такие неэффективные операторы возврата не могут быть замечены. Рассмотрите этот код:
#include<string> class Buffer{ public: //.. const std::string getName() { return m_names; } //... private: std::string m_names; };
Buffer
содержит большой частный объект m_names
. Распространено сделать, чтобы общедоступный метод get функционировал для такого частного объекта, такого как getName
, который возвращает большой объект m_names
. Поскольку тип возврата getNames
установлен как const std::string
вместо const std::string&
, функция возвращает большой объект значением вместо ссылкой. Дорогой возврат копией не может быть замечен, потому что этот код компиляции и функционирует правильно несмотря на недостающий &
. Для подобных источников неэффективности смотрите Expensive pass by value
и Expensive copy in a range-based for loop iteration
.Чтобы зафиксировать этот дефект, возвратите объекты при помощи ссылок. При использовании кода С используйте указатели, чтобы не возвращать объекты значением.
Чтобы возвратить объекты в функцию C++ ссылкой, установите тип возврата функции как ссылка. Например:
#include<string> class Buffer{ public: //.. const std::string& getName() { return m_name; } //... private: std::string m_name; };
getName()
возвращает большой объект m_names
ссылкой, потому что типом возврата функции является const std::string&
, который является ссылкой. В качестве альтернативы используйте указатели, чтобы не возвращать объекты значением. Например, установите тип возврата getName()
к const std::string*
, и затем возвратите адрес m_names
как &m_names
.
#include<string> class Buffer{ public: //.. const std::string* getName() { return &m_name; } //... private: std::string m_name; };
getName()
старается не возвращать m_names
значением. Этот метод полезен в коде С, где ссылки не доступны.Повышения производительности могут варьироваться на основе компилятора, реализации библиотеки и среды, которую вы используете.
Группа: Производительность |
Язык: C | C++ |
Значение по умолчанию: Off |
Синтаксис командной строки:
EXPENSIVE_RETURN_BY_VALUE |
Удар: Средняя |
Expensive copy in a range-based for loop iteration
| Expensive local variable copy
| Expensive pass by value
| Find defects (-checkers)