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

LWG2813 std::function should not return dangling references #1370

Closed
jfbastien opened this issue Nov 24, 2022 · 2 comments
Closed

LWG2813 std::function should not return dangling references #1370

jfbastien opened this issue Nov 24, 2022 · 2 comments
Labels
EWG Evolution
Milestone

Comments

@jfbastien
Copy link
Collaborator

Migrating from https://isocpp.org/files/papers/P1018R18.html#issues

https://cplusplus.github.io/LWG/issue2813

Section: 22.10.17.3.2 [func.wrap.func.con] Status: Resolved Submitter: Brian Bi Opened: 2016-11-03 Last modified: 2022-09-03

Priority: 2

View all other issues in [func.wrap.func.con].

View all issues with Resolved status.

Discussion:

If a std::function has a reference as a return type, and that reference binds to a prvalue returned by the callable that it wraps, then the reference is always dangling. Because any use of such a reference results in undefined behaviour, the std::function should not be allowed to be initialized with such a callable. Instead, the program should be ill-formed.

A minimal example of well-formed code under the current standard that exhibits this issue:

#include <functional>

int main() 
{
  std::function<const int&()> F([]{ return 42; });
  int x = F(); // oops!
}

[2016-11-22, David Krauss comments and suggests wording]

Indirect bindings may also introduce temporaries inside std::function, e.g.:

void f(std::function<long const&()>); // Retains an observer to a long.

void g() {
  int v;
  f([&]()->int& { return v; } ); // int lvalue binds to long const& through a temporary.
}

A fix has been implemented. Conversions that may be conversion operators are allowed, though, because those can produce legitimate glvalues. Before adopting this, it need to be considered considered whether there should be SFINAE or a hard error.

[Issues Telecon 16-Dec-2016]

Priority 2

[2016-07, Toronto Saturday afternoon issues processing]

Billy to work with Brian to rework PR. Status to Open

[2018-08-23 Batavia Issues processing]

Really needs a language change to fix this. Status to EWG.

[2022-08-24 Resolved by P2255R2. Status changed: EWG → Resolved.]

Proposed resolution:

This wording is relative to N4618.

Add a second paragraph to the remarks section of 22.10.17.3.2 [func.wrap.func.con]:

template function(F f);
-7- Requires: F shall be CopyConstructible.

-8- Remarks: This constructor template shall not participate in overload resolution unless

F is Lvalue-Callable (22.10.17.3 [func.wrap.func]) for argument types ArgTypes... and return type R, and

If R is type "reference to T" and INVOKE(ArgTypes...) has value category V and type U:

V is a prvalue, U is a class type, and T is not reference-related (9.4.4 [dcl.init.ref]) to U, and

V is an lvalue or xvalue, and either U is a class type or T is reference-related to U.

[…]

Tim: LWG in Batavia 2018 would like a way to detect when the initialization of a reference would bind it to a temporary. This requires compiler support, since there’s no known way in the current language to do so reliably in the presence of user-defined conversions (see thread starting at https://lists.isocpp.org/lib/2017/07/3256.php).

Meeting:

Tim wrote p2255 to address this.

Ville thinks there should be an analysis of alternative approaches.

Also see P0932.

@jfbastien jfbastien added the EWG Evolution label Nov 24, 2022
@jwakely
Copy link
Member

jwakely commented Nov 24, 2022

P2255 was approved, I think this can be closed.

@jensmaurer jensmaurer added this to the 2023-telecon milestone Jan 25, 2023
@erichkeane
Copy link
Collaborator

EWG discussed this briefly during the May 11th, 2023 telecon, and agreed that there was nothing for us to do, so this is being closed.

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

No branches or pull requests

4 participants