Expensive return by value
Functions return large output by value instead of by reference or pointer
Since R2020b
Description
This defect occurs when functions return large output objects by value instead of the object being returned by reference or pointer.
This checker is raised if both of these conditions are true:
The address of the returned object remains valid after the
return
statement.The returned object is any of these:
A nontrivially copyable object. Returning such an object by value might require an external function call, which is more expensive than returning it by reference. To check whether an object is nontrivially copyable, use the function
std::is_trivially_copyable
. For more details about this function, seestd::is_trivially_copyable
in the C++ reference.A large trivially copyable object. Returning a trivially copyable object by value is more expensive when the object is large.
This defect is not raised if the returned object is:
Inexpensive to copy.
A temporary object or a nonstatic local object.
Risk
It is inefficient to return a large object by value when you can return the object by
reference or pointer. Functions might inadvertently return a large object by value because
of a missing &
or *
. Such inefficient return
statements might not be noticed. Consider this
code:
#include<string> class Buffer{ public: //.. const std::string getName() { return m_names; } //... private: std::string m_names; };
Buffer
contains a large private object m_names
.
It is common to have a public getter function for such a private object, such as
getName
, which returns the large object m_names
.
Because the return type of getNames
is set as const
std::string
instead of const std::string&
, the function
returns the large object by value instead of by reference. The expensive return by copy
might not be noticed because this code compiles and functions correctly despite the missing
&
. For similar sources of inefficiency, see Expensive pass by
value
and Expensive copy in a
range-based for loop iteration
.Fix
To fix this defect, return objects by using references. When using C code, use pointers to avoid returning objects by value.
To return objects from a C++ function by reference, set the return type of the function as a reference. For instance:
The function#include<string> class Buffer{ public: //.. const std::string& getName() { return m_name; } //... private: std::string m_name; };
getName()
returns the large objectm_names
by reference because the return type of the function isconst std::string&
, which is a reference.Alternatively, use pointers to avoid returning objects by value. For instance, set the return type of
getName()
toconst std::string*
, and then return the address ofm_names
as&m_names
.By using a pointer, the function#include<string> class Buffer{ public: //.. const std::string* getName() { return &m_name; } //... private: std::string m_name; };
getName()
avoids returningm_names
by value. This method is useful in C code where references are not available.Performance improvements might vary based on the compiler, library implementation, and environment that you are using.
Examples
Result Information
Group: Performance |
Language: C | C++ |
Default: Off |
Command-Line Syntax:
EXPENSIVE_RETURN_BY_VALUE |
Impact: Medium |
Version History
Introduced in R2020b
See Also
Find defects
(-checkers)
| Expensive pass by value
| Expensive copy in a range-based for
loop iteration
| Expensive local variable
copy
Topics
- Interpret Bug Finder Results in Polyspace Desktop User Interface
- Interpret Bug Finder Results in Polyspace Access Web Interface (Polyspace Access)
- Address Results in Polyspace User Interface Through Bug Fixes or Justifications
- Address Results in Polyspace Access Through Bug Fixes or Justifications (Polyspace Access)