使用GOTO语句仅跳转可能产生的问题?

时间:2010-02-08 13:34:59

标签: c# goto

使用GOTO语句只是跳下来有什么危害吗?还是我们完全安全?

我的意思是将其视为我的代码,

Some code ...
...

GOTO whereToJump

Some code ...
...

whereToJump: 

Some code ...

当whereToJump点始终低于GOTO语句时,是否存在安全问题?

8 个答案:

答案 0 :(得分:2)

这是最着名的计算机科学论文之一。 Dijkstra Go To Statement Considered Harmful。它基本上表明没有人需要goto(我知道总有一些例外)。

这是1968年但今天仍然非常易读。

答案 1 :(得分:1)

有意义的是,只有向下跳跃才能减少意大利面条代码的潜力。 (根据我的经验,调试传统的基于GOTO的代码时头痛的75%来自于这种情况,当向上的结果导致混乱的循环时)

但是,鉴于您只使用向下跳转,转换为非基于goto的代码应该非常容易。我不确定你的提升会提供多少改善。

答案 2 :(得分:1)

在任何更复杂的示例中,当然如果您决定仅使用GOTO在同一范围中跳转,您可以使用if语句。 (如果它不在同一范围内,它不是真的“只是向前跳”,是吗?)

(当然,如果你的真实代码并不复杂,你可以摆脱第二块“一些代码......”)

答案 3 :(得分:1)

这些天应该避免使用GOTO的主要原因是程序员一般不再习惯GOTO(这是一件好事)。因此,如果您编写的代码大量使用GOTO,那么您的程序员很可能难以理解和扩展它。

更糟糕的是,GOTO可能导致破窗综合症,因为同事们开始使用越来越多的GOTO,直到你留下一大碗意大利面。

xkcd说得最好......

alt text

答案 4 :(得分:1)

当需要从许多位置向下jumb到代码块时,我使用goto语句。通常没有goto语句,这可能需要编写另一个函数(以便上面的代码块不会在第一个函数中重复)并在第一个函数内部调用。 goto的效率不低于if或switch语句,因为它还使用了if,switch等使用的jumb语句之一(jz,jnz等)。

答案 5 :(得分:0)

goto 不会使代码不那么安全,而与你跳跃的方式无关。

您可以按照自己喜欢的方式构建代码。您的代码决定代码是好还是坏。在某些情况下可能是合适的(不,我可以展示一个例子:-))

goto的问题在于它可能会隐藏程序中的执行流程并使代码混乱。但是,如果您创建易于阅读/维护的代码,那么这不是问题。

答案 6 :(得分:0)

嗯,真的没问题。该代码相当于:

Some code ...
...

if (false)
{
Some code ...
...
}

Some code ...

那说,我不会这样做。 goto的良好用例非常罕见,其他流控制结构在C#中更为惯用。

答案 7 :(得分:0)

通过这个评论,我并不鼓励使用GOTO,而只是为了说明在一些非常具体的情况下它可能是有用的。到目前为止,在实践中我还没有看到任何使用goto语句向上或向下跳转的代码,但是有一个特定的用例我发现goto更具可读性。以下是我认为goto更有意义的代码示例。

void fun_test ()
{
    .code..
    allocate dynamic memory.
    acquire_lock();

    //do some action, call api. 
    if (some error) {
       print error;
       free memory;
       unlock();
       return FAIL;
    } else {
        // some code.
    }

    if (some_other error) {
        print error;
        free memory;
        unlock();
        return FAIL;
   }
   :
   :
   // more error condition checks.
   :
   return SUCCESS

}

void fun_test_withgoto ()
{
    error_code rc = SUCCESS;
   .code..
   allocate dynamic memory.
   acquire_lock();

   //do some action, call api.
   if (some error) {
       rc = <Failure id>;
       goto function_cleanup;
   } else {
      // some code.
   }

   if (some_other error) {
      rc = <failure id>;
      goto function_cleanup;      
   }
:
:
// more error conditions.
:

function_cleanup:
    if (rc == SUCCESS) {
        print "Success..";
    } else {
        print "Error : <failure id>";
    }
    free_memory();
    unlock();
    return(rc);
}