Main Content

Unnecessary reference to parameter

Parameter is passed to function as const reference when passing by value is more efficient

Since R2024a

Description

This defect occurs when you pass a parameter to a function as a const reference but the parameter is cheap to copy. Polyspace® considers a parameter to be cheap to copy if both of these conditions are true:

  • The parameter is a trivially copyable type. For more on trivially copyable types, see is_trivially_copyable.

  • The parameter size is less than or equal to 2 * sizeof(void *).

Polyspace reports this defect for non-const reference parameters if the parameters are not modified in the function. Taking the address of the passed reference is not considered a modification of the passed reference.

Risk

When you pass a parameter by reference, reading the parameter within the function body requires a dereferencing operation. For cheap-to-copy objects, dereferencing the object in the function scope is more expensive than copying the object into the function scope. Passing parameters by reference can also result in two or more references to the same memory location. In such a case, because the interaction between these references can be difficult to track, the compiler optimizes the code using more conservative assumptions. Passing cheap-to-copy objects by reference can make your code inefficient by requiring expensive dereferencing operations and by hindering compiler optimization.

Fix

To fix this defect, pass cheap-to-copy parameters by value.

Performance improvements might vary based on the compiler, library implementation, and environment that you are using.

Examples

expand all

In this example, Polyspace reports a defect for the parameter r of the setter function setRank(). The parameter r is of type size_t, which is cheap-to-copy. Passing this parameter by reference necessitates expensive dereferencing and hinders optimization, resulting in inefficient code.

#include<string>

class Player
{
public:
    void setName(std::string const& str) //No defect
    {
        name = str;
    }
    void setRank(size_t const& r) //Defect
    {
        rank = r;
    }
    //...
private:
    std::string name;
    size_t rank;

};

Because std::string objects are not cheap to copy, passing std::string objects by reference is not a defect.

Correction — Pass size_t Parameter by Value

To fix this defect, pass r by value.

#include<string>

class Player
{
public:
    void setName(std::string const& str) 
    {
        name = str;
    }
    void setRank(size_t r)
    {
        rank = r;
    }
    //...
private:
    std::string name;
    size_t rank;

};

Result Information

Group: Performance
Language: C++
Default: Off
Command-Line Syntax: EXPENSIVE_PASS_BY_REFERENCE
Impact: Low

Version History

Introduced in R2024a