This question is a slight variant on a related question shown here.
In C++17 I have a local variable that I want to be const to demonstrate it is unmodified once created per Scott Meyers Effective C++ item 3 recommendation to use const whenever possible:
#include <string>
std::string foo()
{
const std::string str = "bar";
return str;
}
int main()
{
std::string txt = foo();
}
Can a compiler perform (named) return-value optimization for txt
, even though the type of str
is different from the return type of foo
due to the const-ness difference?
The named return value optimization is enabled by copy elision specified in C++17 in [class.copy.elision]. The relevant part here is [class.copy.elision]/1.1:
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, even if the constructor selected for the copy/move operation and/or the destructor for the object have side effects. […]
- in a
return
statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function parameter or a variable introduced by the exception-declaration of a handler ([except.handle])) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function call's return object[…]
emphasis mine. Thus, compilers are allowed to perform the optimization here. And a quick test would seem to verify that compilers will actually perform this optimization here…
Note that the const
may be problematic nevertheless. If a compiler does not perform copy elision (it's only allowed, not guaranteed to happen here; even in C++17 since the expression in the return
statement is not a prvalue), the const
will generally prevent the object from being moved from instead (normally cannot move from const
object)…