例如:
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);
}
}这样上面的代码将打印从1到42的所有数字。我想让yield把getNext的地址改成yield之后的指令。但是我不知道如何保存上下文(寄存器/变量),因为堆栈将被调用者函数遍历。
注意:
我意识到上面的代码可以很容易地通过静态变量实现,但这不是重点。
发布于 2013-07-05 15:52:23
你可以这样做,即使在可移植的C中也是如此。下面是一个简单的例子(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;
}发布于 2013-07-05 09:00:54
你正在寻找的东西被称为“协程”,并且(至少不是没有失去通用性--在有限的情况下,请参阅另一种方法)在可移植C中是不可能的。你可以通过许多技巧来伪造它们;请参阅http://en.wikipedia.org/wiki/Coroutine#Implementations_for_C中的几个。
https://stackoverflow.com/questions/17478264
复制相似问题