Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[class.copy.elision] p3 The return type in the first bullet should be restricted #4839

Open
xmh0511 opened this issue Aug 26, 2021 · 4 comments · May be fixed by #4842
Open

[class.copy.elision] p3 The return type in the first bullet should be restricted #4839

xmh0511 opened this issue Aug 26, 2021 · 4 comments · May be fixed by #4842

Comments

@xmh0511
Copy link
Contributor

xmh0511 commented Aug 26, 2021

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 is first considered before attempting 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
  • [...]

overload resolution to select the constructor for the copy or the return_­value overload to call is first performed as if the expression or operand were an rvalue. If the first overload resolution fails or was not performed, overload resolution is performed again, considering the expression or operand as an lvalue.

Consider this example

struct A{
    A(){}
    A(A const&){
        std::cout<<"copy\n";
    }
    A(A&&){
        std::cout<<"move\n";
    }
};
A& fun(A x){
    return x;
}
A a;
A b = fun(a);

According to the rule, id-expression x in the return statement does name an implicitly movable entity. However, that rule indeed does not apply to this example. Shouldn't we restrict that the return type, in either case, shall be (possible cv-qualified) class type?

@jensmaurer
Copy link
Member

This is likely undefined behavior anyway, because you're returning a reference to a by-value parameter, which might be destroyed early [expr.call] p7.

Also, the normative text says we try a move-construction in this case, which attempts to initialize an A& with xvalue referring to A, which fails, so we fall back to copy-initialization, which succeeds (as-if there was no implicitly movable entity).

@xmh0511
Copy link
Contributor Author

xmh0511 commented Aug 26, 2021

However, in this example, the reference A& could say is reference-compatible with the type of the operand. There is no overload resolution occurs here. Anyway, I think the rule just considers the case that the return type is object type.
Maybe we could say

the copy-initialization or overload resolution is first performed as if the expression or operand were an rvalue. If that copy-initialization is ill-formed or the overload resolution fails, then the copy-initialization or overload resolution is performed again, considering the expression or operand as an lvalue.

This could cover all the cases rather than only the case used overload resolution(p.return_­value( expr-or-braced-init-list
) directly causes the overload resolution). The return or throw-expression may indirectly cause the overload resolution(i.e. the target or source has class type) but is not necessary.

@jensmaurer
Copy link
Member

Ah, the point is that that the copy/move section talks about overload resolution, but in your case, there is none. This entire section should only apply to objects. We say that in p1, but that context is arguably lost in p3.

@frederick-vs-ja
Copy link
Contributor

The concerns are probably invalidated by P2266R3 which considers reference return types...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants