在一个小型嵌入式系统上工作时,我想尝试使用开关/案例/宏构造和gcc标签作为值扩展实现的C协同程序。所以我提出了一些结构和函数以及一个模式,以便我可以编写如下函数(只是一个测试/示例函数):
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 *成员)。我的想法基本上就是,当我在外部结构中返回时,我会抓住标签跳转到该函数,然后返回跳转到新标签。
我认为,我所得出的结论是,海湾合作委员会并不知道如何做到这一点,因为&& amp;& amp;&运算符产生绝对跳转地址,而不是相对于当前函数堆栈的跳转地址。所以我无法安全地重复使用它,因为没有什么可说的,我不会用不同的堆栈深度来调用这个函数。
所以我的问题基本上是双重的。我是否理解为什么它不会工作/编译?或者它是别的东西,如果是这样,我对这个功能做错了什么?我只用gcc -std=gnu99
编译。
答案 0 :(得分:1)
尝试
goto *(fiber->restore);
见
http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html
此外,堆栈深度对于函数代码地址无关紧要 - 只有共享库重定位才能执行(上面的页面也解释了如何很好地执行此操作)。