【发布时间】:2010-12-30 23:53:58
【问题描述】:
我正在为我正在编写的解释器添加协程支持,我想做如下的事情:
typedef enum {
bar_stuff,
bar_other
} Bar;
typedef enum {
foo_error=-1,
foo_none=0,
foo_again
} Foo_state;
Foo_state do_foo(Bar bar,Foo_state foo)
{
switch(foo)
{
case foo_none: //start
switch(bar)
{
case bar_stuff:
//do stuff
return foo_none;
case bar_other:
//do other stuff
return foo_again;
case foo_again: //!! this doesn't work
/* edit: this is supposed to be a case of
* switch(foo), not switch(bar)
*/
//do more other stuff
return foo_none;
default:
//stuff
return foo_none;
}
default:
//fail
return foo_error;
}
}
显然这不起作用(我得到重复的案例值,替代可能是未定义的行为/段错误)。我可以将 switch(bar) 写成 if/else if/else 链,但我希望有更好的方法。
如果有什么不同,我会使用 gcc。
编辑:
以下内容可行,但需要维护一个 PITA:
Foo_state do_foo2(Bar bar,Foo_state foo)
{
switch(foo)
{
case foo_none: goto case_foo_none;
case foo_again: goto case_foo_again;
default:
//fail
return foo_error;
}
case_foo_none: //start
switch(bar)
{
case bar_stuff:
//do stuff
return foo_none;
case bar_other:
//do other stuff
return foo_again;
case_foo_again:
//do more other stuff
return foo_none;
default:
//stuff
return foo_none;
}
}
编辑 2:
嗯,这似乎并没有产生上述“更好的方法”,所以我想知道是否有人预见到这样写会出现问题:
Foo_state do_foo3(Bar bar,Foo_state foo)
{
switch(foo)
{
case foo_none: //start
if(bar == bar_stuff)
{
printf("do stuff\n");
return foo_none;
}
else if(bar == bar_other)
{
printf("do other stuff\n");
return foo_again;
case foo_again: //continue
printf("do more other stuff\n");
return foo_none;
}
else
{
printf("stuff\n");
return foo_none;
}
default:
//fail
return foo_error;
}
}
我看到的问题是缺少一个 bar_* 值(因为有几个这样的函数,并且一些枚举有几十个值),但我想一个测试脚本应该可以工作......
【问题讨论】:
-
当你说你想要“类似下面的东西”然后发布无效代码时,我们应该认为你真正想要什么?如果该代码有效,它会做什么?
-
是的,PITA 是对的……为什么不在纸上画出一个状态机,在纸上简化它,然后想出至少可以自我记录这个过程的变量的正确名称到一个程度?您正在用这些变量表示一个状态。为什么不使用单个变量来表示状态?
-
我发布了一个参考,说明我的意思是如何工作。 (但我希望找到一种不那么丑陋的方法。)
-
说真的,在 Excel 中画一个 3 x 3 的表格,列出要执行的东西和要返回的值。一起阻止条件。 upload.wikimedia.org/wikipedia/commons/0/02/… 你可以使用另一个快捷方式 if(foo_again && bar_other) { ... } 那应该只剩下一个 switch 语句。
-
可能有用:blog.think-async.com/2009/08/secret-sauce-revealed.html(虽然其中一些是 C++ 特定的,但 switch hack 在 C 中是相同的,它展示了如何从单个逻辑中提取“共同调用”。 )
标签: c language-design interpreter coroutine