在一个小型嵌入式系统上工作时,我想尝试使用诸如 C 协程之类的东西,你发现这些协程是用 switch/case/macro 结构和 gcc 的标签作为值扩展来实现的。所以我想出了一些结构和函数以及一个模式,这样我就可以编写如下函数(只是一个测试/示例函数):
void fiber1(FiberContext *fiber)
{
if (fiber->restore) goto fiber->restore; // initial jump if called for
stateA:
printf("Fiber 1: A state\n");
fiber->misc = &&stateB;
fiber->restore = &&sleep;
return;
stateB:
printf("Fiber 1: A state\n");
fiber->misc = &&stateA;
fiber->restore = &&sleep;
return;
sleep:
fiberSleepTicks(fiber, 1000000);
fiber->restore = fiber->misc ? fiber->misc : &&stateA;
return;
}
但是 GCC 不喜欢原来的goto fiber->restore
(restore
是 FiberContext 的 void* 成员)。我的想法是,基本上,当我在外部结构中返回时,我会捕获要跳转到的标签,离开函数,然后返回并跳转到新标签。
我认为,我得出的结论是 GCC 不知道该怎么做,因为 && 运算符产生一个绝对跳转地址,而不是相对于当前函数堆栈的跳转地址。所以我不能安全地重用它,因为没有什么可说的,我不会用不同的堆栈深度调用这个函数。
所以我的问题基本上是双重的。我对为什么它不起作用/编译的理解正确吗?或者是别的什么,如果是这样,我在这个功能上做错了什么?我正在编译只是gcc -std=gnu99
.