C++ Logo


Advanced search

Re: inline coroutine generators

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Thu, 9 Dec 2021 12:16:55 -0500
On Thu, Dec 9, 2021 at 11:28 AM Phil Endecott via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> Dear Experts,
> I have recently been experimenting with generators for the
> first time.
> One issue that bothers me is inlining. For example:
> generator<char> g1()
> {
> for (.....) {
> co_yield x;
> if (......) g2(a);
> if (......) g2(b);
> g2(a+b);
> }
> }
> static ??? g2(int)
> {
> for (....) {
> co_yield ....;
> }
> }
> What I'm trying to convey with that pseudocode is that I've
> decomposed a largish block of code by factoring out some common
> bits into another routine.

"Inlining" does not mean you get to ignore C++'s rules. An inline
function that issues a return doesn't cause the function that called
it to return to *its* caller. If your intent is for `g2`'s `co_yield`
to cause `g1` to yield, then you can't. A function cannot force
another function to yield or return (the only exception being...
exceptions). `g1` yields exactly and only when it executes a
`co_yield` expression.

Some people have suggested ways to write some kind of named statements
or expressions that behaves as if it were within the invoking code.
But along that road lies madness. It becomes *way* too easy to hide
control flow. One of the most persistent criticisms of exceptions is
that they obscure control flow, and what you're suggesting would do
this even moreso.

Functions exporting control flow like `return`, `co_yield`, or even
`break` and `continue` is just a bad idea.

Received on 2021-12-09 11:19:31