Implementation of yield in C

For example:

int getNext(int n) { while (TRUE) { n = n+1; yield n; } } int main() { while (TRUE) { int n = getNext(1); if (n > 42) break; printf("%d\n",n); } } 

Thus, the above code will print all numbers from 1 to 42. I was thinking of making yield change the getNext address to an instruction after yield . But I can’t understand how to save the context (registers / variables), since the stack will be launched by the caller function.

Note:

I understand that the above code can be easily implemented by static variables, but that is not the point.

+7
c yield
source share
2 answers

You can do this, even in portable C. Here is a rough example that works ( gcc -Wall gen.c ):

 #include <stdbool.h> #include <stdio.h> #include <setjmp.h> #define YIELD(func, n) if (! setjmp(func##_gen_jmp)) { \ func##_ret = n; \ longjmp(func##_caller_jmp, 1); \ } #define GENERATOR(ret, func, argt, argv) \ static jmp_buf func##_caller_jmp; \ static jmp_buf func##_gen_jmp; \ static bool func##_continue=false; \ static ret func##_ret; \ \ void func##__real(argt argv); \ \ ret func(argt argv) { \ if (!func##_continue) { \ func##_continue=true ; \ if (! setjmp(func##_caller_jmp)) { \ func##__real(argv); \ } else { \ return func##_ret; \ } \ } \ else { \ longjmp(func##_gen_jmp,1); \ } \ return 0; \ } \ void func##__real(argt argv) GENERATOR(int, getNext, int, n) { static int counter; counter = n; while (true) { counter = counter+1; YIELD(getNext, counter); } } int main() { while (true) { int n = getNext(1); if (n > 42) break; printf("%d\n",n); } return 0; } 
+10
source share

What you are looking for is called "coroutines" and (at least without loss of generality - see another answer for the method of its implementation in limited cases) is not possible in figurative C. There are a number of tricks with which you can fake them; see http://en.wikipedia.org/wiki/Coroutine#Implementations_for_C for a few.

+1
source share

All Articles