C++ Logo


Advanced search

Re: [std-proposals] long return lambda

From: Sebastian Wittmeier <wittmeier_at_[hidden]>
Date: Tue, 11 Apr 2023 18:47:24 +0200
Invoking a lambda can be implemented by the compiler as any other function call. It will not necessarily be inlined.   So for implementing your suggestion, you either would use the existing, or one of the proposed (lower overhead?) alternative exception mechanisms, or you would propose some way for an inlined-only function to `goto` or `break` or `return` several scope levels.   In the first of those two cases, the optimizer could choose to inline the function and sometimes or often provide good performance,   in the second case you could get guarantees that the jump targets can be resolved. But then still scopes are left on the way and local objects have to be destructed. How much more optimization would you get by guarantee? So I do not think that it would make sense to invent another exception-like feature, which is distinct from current or improved exceptions, and only works for a new special class of lambdas (and not for all plain functions), which are guaranteed to be inlined (instead of for all lambdas).   -----Ursprüngliche Nachricht----- Von:Phil Endecott via Std-Proposals <std-proposals_at_[hidden]> Gesendet:Di 11.04.2023 18:24 Betreff:[std-proposals] long return lambda An:std-proposals_at_[hidden]; CC:Phil Endecott <std_proposals_list_at_[hidden]>; Frederick Virchanza Gotham wrote: > So I thinking, what if we had a 'long return lamda'? The return > statement from a 'long return lambda' is treated as a return statement > from the enclosing function. This is similar to the desire to be able to break, continue or return from within a loop that takes a lambda. For example, say I want to iterate over the edges of a polygon: Polygon p = ....; for (auto e: edges(p)) {  // In here I can use break and continue, and return  // will return from the function. } But what is edges(p) there? Maybe it is a generator coroutine; maybe it is a function that returns a lazy range. It's probably simpler to write a foreach function that takes a lambda, like this: foreach_edge(p, [&](auto e) {  // In here, I can't use break or continue, and return  // just returns from the lambda. }); (The different behaviour of return is perhaps dangerous, i.e. one might write "return" imagining a return from the function, and not get a warning or error.) There have been suggestions that break and continue should be extended to support nested loops: outer: for (auto a: A) {  inner: for (auto b: B) {    if (....) continue outer;  } } Generally the response to these suggestions have been "just use goto". So how about this: foreach_edge(p, [&](auto e) {  if (....) goto break_outer; }); break_outer: .... Similarly, in Frederick's example, "just use goto": bool Serial(char *const p) {  auto BAIL = [p](void)->void {    strcpy(p, "0000000000000000");    goto Serial_return;  };  ........  Serial_return: ... } Currently goto can't exit a lambda. Though of course exceptions can do that. So here is my suggestion: make it possible to exit lambdas with goto, with the same/similar semantics to throwing and catching an exception. Can that be implemented with lower overhead than actually using an exception? Regards, Phil. -- Std-Proposals mailing list Std-Proposals_at_[hidden] https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2023-04-11 16:47:26