Функция на C может вернуться из `return`, а при следующем вызове продолжить с того же места. Для этого хватит трёх макросов.
Создатель PuTTY Саймон Тэтем описал трюк, который имитирует корутины в обычном C с помощью switch/case и __LINE__.
define crBegin \
static int state = 0; switch (state) { case 0:
define crYield(x) do { \
state = __LINE__; return (x); \
case __LINE__:; \
} while (0)
define crFinish }
int next_value(void) {
crBegin;
while (1) {
crYield(10);
crYield(20);
crYield(30);
}
crFinish;
}
Последовательные вызовы next_value() вернут 10, 20, 30, 10…
Как это работает: перед выходом функция сохраняет номер строки в static`-переменной. При следующем вызове `switch переводит выполнение к соответствующему case, прямо за предыдущий return.
Зачем это нужно: обработчик протокола или парсер можно написать последовательным кодом, выдавая результат по частям.
Есть ограничения: обычные локальные переменные не сохраняются между вызовами, два crYield нельзя размещать на одной строке, а static хранит одно общее состояние для всех вызывающих. Для независимых экземпляров состояние выносят в отдельную структуру.
www.chiark.greenend.org.uk/~sgtatham/coroutines.html