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] p2 incorrect comment in copy elision example #4926

Closed
RazvanAM opened this issue Sep 22, 2021 · 4 comments · Fixed by #4928
Closed

[class.copy.elision] p2 incorrect comment in copy elision example #4926

RazvanAM opened this issue Sep 22, 2021 · 4 comments · Fixed by #4928
Assignees

Comments

@RazvanAM
Copy link

Paragraph 2 of [class.copy.elision] (https://eel.is/c++draft/class.copy.elision#2) contains the following example:

[...]

constexpr A g() {
  A loc;
  return loc;
}

constexpr A a;          // well-formed, a.p points to a
constexpr A b = g();    // error: b.p would be dangling ([expr.const])

void h() {
  A c = g();            // well-formed, c.p may point to c or to an ephemeral temporary
}

I believe the comment "well-formed, c.p may point to c or to an ephemeral temporary" is not entirely correct, because there is no temporary in this scenario.

This comment was originally added with the resolution of CWG2002. The example used in that resolution was:

[...]

struct A {
    void *p;
    constexpr A(): p(this) {}
  };

  constexpr A a;        // well-formed, a.p points to a
  constexpr A b = A();  // well-formed, b.p points to b

  void g() {
    A c = A();          // well-formed, c.p may point to c or to an ephemeral temporary
  }

In this resolution the comment "well-formed, c.p may point to c or to an ephemeral temporary" correctly reflects the code.

After the resolution of CWG2002 the code in the example was modified in 95321805a3, but the comment was not changed to reflect this.

@xmh0511
Copy link
Contributor

xmh0511 commented Sep 23, 2021

Agree that comment is not correct. Since both [class.copy.elision]p1 and [expr.const] p1 says

Copy elision is not permitted where an expression is evaluated in a context requiring a constant expression ([expr.const]) and in constant initialization ([basic.start.static]).

Hence, for A c = g(); , c.p may point to loc, or point to an ephemeral temporary as per [class.temporary] p3, depends on which initializer expression performs the copy-initialization of c.

@jensmaurer
Copy link
Member

There is no temporary here; the result of g() is an rvalue whose target object is c.

@xmh0511
Copy link
Contributor

xmh0511 commented Sep 24, 2021

When an object of class type X is passed to or returned from a function, if X has at least one eligible copy or move constructor ([special]), each such constructor is trivial, and the destructor of X is either trivial or deleted, implementations are permitted to create a temporary object to hold the function parameter or result object. The temporary object is constructed from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by using the eligible trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object).

There can have a temporary here.

@jensmaurer
Copy link
Member

jensmaurer commented Sep 24, 2021

Good point. I think the pull request is correct regardless, because c.p will be dangling at the end either way.

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