WilliamKF
WilliamKF

Reputation: 43099

Can a C++ compiler perform RVO for a named const variable used for the return value?

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?

Upvotes: 8

Views: 1481

Answers (2)

vlad1q
vlad1q

Reputation: 11

Agree with Michael Kenzel's answer. But there are some peculiarities with compiler optimizations. If you look at a simple example without optimizations, you can see a feature of the msvc compiler - https://godbolt.org/z/b7z6n1YMf

Without optimizations, msvc will produce a copy of the object instead of NRVO. This may be important in some cases.

Upvotes: 0

Michael Kenzel
Michael Kenzel

Reputation: 15943

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)…

Upvotes: 7

Related Questions