goto的C用法

C usage of goto

我有一个带有某种回调机制的状态机,函数由任务运行器调用。所有这一切的背后是一个状态机,它有 4 种状态,一些状态相互排斥,另一些状态可以组合,这构成了一个相当复杂的规则集。如果尝试进行任何非法操作,其中一个函数应向用户显示错误消息(为简单起见,此处 printf):

static int state1 = 0;
static bool switch2 = 1;

void do_stuff(int value){
    int errorCode = 0;
    if(state1 == 1){ 
        errorCode = -1;
        goto ERROR;
    }
    if(state1 == 2 && switch2)
    {
        errorCode = 2;
        goto ERROR;
    }


    printf("No error!");
    return;
ERROR:
    printf("%d", errorCode);
}

这是我能想到的最短、最简洁的方法,但人们一直认为使用 goto 是一件坏事。有没有更好的方法来解决这个问题,或者这是稳定性和维护方面的最佳方法?

goto 很少 是控制流的正确解决方案。虽然 goto 有有效的用例,但在这个特定函数中,您可以简单地将控制流重组为 if-else 分支,如下所示:

void do_stuff(int value)
{
    int errorCode = 0;

    if (state1 == 1)
    { 
        errorCode = -1;
    }
    else if (state1 == 2 && switch2)
    {
        errorCode = 2;
    }
    else // unconditional case for no errors
    {
        printf("No error!");
        return;
    }
    printf("%s", errorCode);  // if control reaches here, print the error
}

据我所知,您正在使用 goto 进行错误处理,而不是状态机。

使用 goto 进行错误处理实际上是其中一种非常有用和首选的情况,而不是复杂的条件链。它允许您执行手动 RAII 而无需重复代码:

int do_stuff(...)
{
    ... = f1(...);
    if (...)
        goto ERROR_f1;

    ... = f2(...);
    if (...)
        goto ERROR_f2;

    ... = f3(...);
    if (...)
        goto ERROR_f3;

    // Success
    return ...;

ERROR_f3:
    undo_f2(...);

ERROR_f2:
    undo_f1(...);

ERROR_f1:
    return ...;
}