为什么goto语句在C++中被视为禁忌?

jkl*_*ara 2 c++ syntax goto

我几个月来一直用C++编程,当我通过论坛时,我注意到了一个趋势.看来,goto语句通常被视为是要么完全错误使用,或只在非常特殊的情况下使用.什么是goto使它们如此根本错误的陈述?

sig*_*ned 7

最大的原因是它使代码很难遵循.这goto不是暗示坏事; 使用它编写难以理解的代码很容易.

例如,您宁愿阅读哪个?这个:

int factorial(int n) {
    int result;

    if(n==0 || n==1)
        result = 1;
    else
        result = n*factorial(n-1);

    return result;
}
Run Code Online (Sandbox Code Playgroud)

或这个:

int factorial(int n) {
    int result;

    if(n > 1)
        goto big;

    result = 1;
    goto end;

big:
    result = n*factorial(n-1);

end:
    return result;
} 
Run Code Online (Sandbox Code Playgroud)

这两种实现方式与机器相同,但第一种对我们的人眼来说更清晰.有些时候goto 清晰的,但.例如,从C(或C++没有例外)考虑这个:

void process_big_file(FILE* foo) {
    if(possible_failure_1(foo))
        goto cleanup;

    // Do some work

    if(possible_failure_2(foo))
        goto cleanup;

    // Do some more work

cleanup:
    fclose(foo);
}
Run Code Online (Sandbox Code Playgroud)

在这里,使用goto是有意义的,因为它允许您将所有清理代码放在一个地方,而gotos实际上创建了一个逻辑执行流程.特别是,在阅读代码时,很明显你总是(a)达到清理代码,并且(b)总是达到相同的清理代码,这是重要的事情.在没有例外的情况下,我实际上认为goto在尝试组织(例如)清理代码时,这是正确的事情.

  • 最后一个例子永远不应该在C++中使用.即使没有例外,您也总是使用RAII,它也可以使用错误代码/早期返回. (2认同)