
Coroutines in C (2000) - adamnemecek
http://www.chiark.greenend.org.uk/~sgtatham/coroutines.html#
======
stormbrew
Some extra fun (and obscene) things along this line:

\- Use __LINE__ to make it so you don't have to manually specify the
continuation number (with the caveat that you can't have more than one on a
line).

\- Use computed goto and labels rather than a switch and you can make it work
even inside a switch (&&label to take the address, goto *addr to goto). This
is a gcc extension.

\- Use clang blocks to save state and return the block for continuation,
saving you from needing to use static functions. Perhaps you could also use
C++ lambdas along the same line, but I'm not sure if they mix well with the
&&label thing.

~~~
apaprocki
I'm pretty sure the code in the article could use __COUNTER__ followed by
__COUNTER__-1 in the macro to avoid the __LINE__ collision and allow more than
one yield on the same line.

------
majke
Let me rant about a bigger point: What are coroutines conceptually? Well, it's
a "thing" that we use in order to express sequential code (I'm sure there is
more abstract definition).

What is a difference between Erlang Proc, Golang Goroutine, Operating System
Thread, and this kind of Duff's device - not much if you think about it. It's
all about sequential code with a bit of context (variables) attached - the
closure.

The only difference between a thread and asynchronous programming is how you
deal with the context - is it explicit or implicit?

In this Duff's device, the context is passed explicitly. It's an (arguably
nice) syntactic sugar over a trivial state machine.

The main point here is - how large is the context? If that's a few variables,
sure you can pack them on a struct, or just async programming. If the context
is somewhat non-trivial, having it implicit makes sense. If the context is
really large you probably _must_ use OS / programming language help.

The problem - the larger the context, the costlier the context switch. It
would be nice to have some kind of magic that would be able to chose the
optimal coroutines hardware implementation based on the size of context.

~~~
greggman
> The only difference between a thread and asynchronous programming is how you
> deal with the context

Coroutines are not threads. Each serve vastly different purposes. Coroutines
are basically an easier way of expressing certain kinds of state machines.
They're great for games when you need a character or other game object to
progress through different states. They free you from 3-10x boilerplate that
would be required if you had to write and manipulate a state machine directly.
They're not related to threading whatsoever.

------
iokevins
Today I learned: "PuTTY is a Win32 Telnet and SSH client. The SSH protocol
code contains real-life use of this coroutine trick. As far as I know, this is
the worst piece of C hackery ever seen in serious production code."

~~~
O5vYtytb
Wow,no kidding
[https://github.com/Yasushi/putty/blob/31a2ad775f393aad1c31a9...](https://github.com/Yasushi/putty/blob/31a2ad775f393aad1c31a983b0baea205d48e219/ssh.c#L414)

It's beautiful and incredibly scary at the same time.

~~~
majke
just wow, from the snippet you linked:

    
    
      *  - right-click ssh.c in the FileView
      *  - click Settings
      *  - select the C/C++ tab and the General category
      *  - under `Debug info:', select anything _other_ than `Program
      *    Database for Edit and Continue'.
    

Right, so in order to compile the thing you need to click "something other
than". That doesn't sound deterministic.

~~~
becauseICan
That's ensuring the compiler obeys some behaviors of an ANSI C compiler when
debugging in MS Visual Studio. That strikes me as the kind of practice that
would improve determinism. The explanation is given on the line before your
quote.

That said, I can't believe this exists in the wild.

------
cm2187
And people are giving shit to VB for having a GoTo statement!

