Automatic move from local variables when variable is rvalue reference

Viewed 151

According to cppreference, in return statement, local rvalue references should be moved from in C++20:

Automatic move from local variables and parameters

  • If expression is a (possibly parenthesized) id-expression that names a variable whose type is either

  • a non-volatile object type or a non-volatile rvalue reference to object type (since C++20)

I tried the second bullet point (godbolt):

#include <cstdio>

struct Foo {};

struct Bar {
    Bar() = default;

    Bar(const Foo &) {
        printf("copy!\n");
    }
    Bar(Foo &&) {
        printf("move!\n");
    }
};

Bar foo() {
    Foo f;
    Foo &&rf = static_cast<Foo &&>(f);
    return rf;
}

int main() {
    foo();
}

I expected that this program prints move!. But actually, both clang and gcc prints copy!. Is this something which haven't been implemented yet in compilers? Or do I misunderstand something?

1 Answers

Is this something which haven't been implemented yet in compilers?

Not implemented yet (look for P1825), you understand the rule correctly. But let's go through it to be sure. The specific standard text here is in [class.copy.elision]/3:

An implicitly movable entity is a variable of automatic storage duration that is either a non-volatile object or an rvalue reference to a non-volatile object type. In the following copy-initialization contexts, a move operation might be used instead of a copy operation:

  • If the expression in a return ([stmt.return]) or co_­return ([stmt.return.coroutine]) statement is a (possibly parenthesized) id-expression that names an implicitly movable entity declared in the body or parameter-declaration-clause of the innermost enclosing function or lambda-expression, or
  • if the operand of a throw-expression is a [...]

rf is an rvalue reference (check) to Foo (non-volatile object type, check), which makes it an implicitly movable entity. In return rf;, that's an id-expression that names an implicitly movable entity (check) declared in the body of the function (check). So, we move instead of copy.

Related