Main Content

Expensive return caused by unnecessary std::move

An unnecessary call to std::move in the return statement hinders return value optimization, resulting in inefficient code

Since R2022b

Description

This defect occurs when you use std::move to force the compiler to return a local variable from a function by using move semantics. Polyspace® reports a defect if the returned local variable satisfies all of these requirements:

  • It is not a volatile object.

  • It is not an input parameter of the function or a catch block.

  • It has the same type as the return type of the function.

  • It is returned by using std::move.

In this code, a local object is returned by using std::move. Polyspace flags the return statement.

class A{};
A func(A a){
A local_obj;
return std::move(local_obj);
}

The C++ standards define the necessary conditions when compilers are permitted to perform return value optimization. For more information, see copy elision.

Risk

In C++, compilers can optimize return values by omitting the call to a copy or move constructor when returning objects. Using std::move to return certain local objects might stop the compiler from attempting this optimization, which results in inefficient code. This inefficiency might be difficult to diagnose because the code compiles and behaves correctly.

Fix

Remove the call to std::move in return statements.

Performance improvements can vary based on your compiler, library implementation, and environment.

Examples

expand all

#include<vector>
template<typename T>
std::vector<T> vectorFactory(size_t size)
{
    std::vector<T> bigdata;
	//...
	return std::move(bigdata);
}

class data{
	char* name;
	char* address;
	public:
	data():name(nullptr), address(nullptr){}
	//...
};
void foo(){
	std::vector<data> database = vectorFactory<data>(5);
}

In this example, the function template vectorFactory returns a vector of objects. Calling std::move in the return statement might hinder return value optimization, which results in inefficient code. Polyspace reports a defect.

Correction — Allow Return Value Optimization

To facilitate return value optimization by the compiler, avoid using std:move in the return statement.

#include<vector>
template<typename T>
std::vector<T> vectorFactory(size_t size)
{
    std::vector<T> bigdata;
	//...
	return bigdata;
}

class data{
	char* name;
	char* address;
	public:
	data():name(nullptr), address(nullptr){}
	//...
};
void foo(){
	std::vector<data> database = vectorFactory<data>(5);
}

Result Information

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

Version History

Introduced in R2022b