On Wed, Jan 29, 2025 at 10:35 AM Peter Bindels via Std-Proposals <std-proposals@lists.isocpp.org> wrote:On Wed, Jan 29, 2025 at 3:55 PM Karl Semich via Std-Proposals <std-proposals@lists.isocpp.org> wrote:> > I'm trying out c++23 std::generator and noticing that I cannot safely pass arguments to my generators that are temporaries such as std::initializer_list. It seems like this is because promise_type's initial_suspend returns suspend_always, so passed temporaries are out of scope as soon as initial code is executed.> > Where can I read about this and best practices, or is it a mistake? It looks like a mistake to me.Thanks, that wrapper solution is just the thing!
I didn't find a way that move semantics would help with the argument case; the temporaries still go out of scope before data can be moved in (unless one uses a wrapper function, a patch, or writes their own generator).
Given when a wrapper function is not used that the misbehavior is (a) severe, (b) undocumented, and (c) not reported by compilers and implementations, my personal opinion is still that this is a bug.
The standard should clearly state that passing temporaries to a generator or defining temporary generators is illegal or at least undefined.Unfortunately C++ (language and/or library) cannot detect when a reference (or string_view or function_ref or whatever) refers to a temporary. We can detect value category, but value category is not lifetime. It's legal and not even uncommon for an rvalue reference to refer to a "long-lived-enough" object; and it's extremely common to have a (const) lvalue reference that refers to a short-lived temporary.However, if generators executed eagerly, it would prevent a wide class of these memory corruption errors.This to me reads like a great argumentation to put into a paper, that can be submitted for inclusion into C++26 or 29. If we have a known-bug-inducing current setup, that is not used much, that we can then still fix and have working in C++26/29, it would make sense to write a paper & to see if it can be seen at Austria - or shortly after. Teaching everybody "generator is kinda broken and you need to define this wrapper function" seems counterproductive, when we can propose to change "suspend_always" to "suspend_never" in one location and fix it for everybody.I agree that at first glance it seems like std::generator shouldn't suspend_always... but I'm sure there is some concrete reason that P2168 made it suspend_never. Cc'ed the paper authors in case they want to give an authoritative-ish answer, and/or suggest a workaround.–Arthur