C嵌套开关:内部开关内的外部开关盒

Dav*_*d X 1 c interpreter language-design coroutine

我正在为我正在写的翻译添加协程支持,我想做类似以下的事情:

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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

显然这不起作用(我得到重复的案例值,替代可能是未定义的行为/段错误).我可以将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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

编辑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;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我看到的问题是缺少bar_*值(因为有几个这样的函数,有些枚举有几十个值),但我想这个测试脚本应该有用......

Mar*_*ett 6

您也可以将{}放在每个case:语句中,
不使用它们将整个案例堆栈评估为单个单元,因此在一个案例中不能定义任何变量:

但通过推杆

 case blah:
 {
  // do stuff
 }
 break;
Run Code Online (Sandbox Code Playgroud)

你可以在case语句中放入你想要的任何符号.