Main Content

Expensive return of a const object

The return statement of a function copies an objects instead of moving it because the returned object is declared as a const

Since R2022a

Description

This defect occurs when these conditions are true:

  • A function returns a const object, forcing a copy construction of the returned object from a const object.

  • The returned object implements an available move constructor.

For instance, consider this code:

std::string foo(const std::string& str){
	const std::string cstr{str};
	//...
	return cstr;
}
The string cstr is constructed from a const string. Because cstr is a const, the return statement copies it instead of moving it. Polyspace® flags the declaration of cstr.

Risk

When returning objects, compilers implicitly attempt moving the returned object instead of copying it when the object supports move semantics. When you declare an object as a const, this implicit move is suppressed and the compiler copies the object. When the return statement copies the constructed return object instead of moving it, the code becomes less efficient. Because the inefficient code compiles and behaves correctly, the inefficiency might be difficult to diagnose.

Fix

To fix this defect, make the returned object into a nonconst.

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

Examples

expand all


#include <string>

class Task
{
public:
    std::string exchangeName( const std::string& name )
    {
        const std::string old_name = m_name;
        m_name = name;
        return old_name; 
    }
     //...
private:
    std::string m_name;
};

In this example, the function exchangeName returns the string old_name, which is a const object. The compiler cannot move old_name. The return statement of the function exchangeName is forced to copy the constructed return object, which is inefficient. Polyspace flags the declaration of old_name.

Correction — Return Nonconst Objects

To facilitate implicit move operation when returning an object, declare the returned objects as nonconst.


#include <string>

class Task
{
public:
    std::string exchangeName( const std::string& name )
    {
        std::string old_name = m_name;
        m_name = name;
        return old_name; 
    }
     //...
private:
    std::string m_name;
};

Result Information

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

Version History

Introduced in R2022a