使用GOTO语句只是跳下来有什么危害吗?还是我们完全安全?
我的意思是将其视为我的代码,
Some code ...
...
GOTO whereToJump
Some code ...
...
whereToJump:
Some code ...
当whereToJump点始终低于GOTO语句时,是否存在安全问题?
答案 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说得最好......
答案 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);
}