僅使用GOTO語句跳下來會有什麼壞處嗎?或者我們完全安全?使用GOTO語句只能跳轉出現的問題?
我的意思是覺得這是我的代碼,
Some code ...
...
GOTO whereToJump
Some code ...
...
whereToJump:
Some code ...
當whereToJump點總是GOTO語句下面,有沒有安全問題?
僅使用GOTO語句跳下來會有什麼壞處嗎?或者我們完全安全?使用GOTO語句只能跳轉出現的問題?
我的意思是覺得這是我的代碼,
Some code ...
...
GOTO whereToJump
Some code ...
...
whereToJump:
Some code ...
當whereToJump點總是GOTO語句下面,有沒有安全問題?
轉到不會讓代碼不那麼安全,不管你跳哪種方式。
您以任何喜歡的方式構建您的代碼。這是你的代碼決定代碼是好還是壞。 goto也許在某些情況下是適當的(不,我可以展示一個例子:-))
goto的問題是它可能會隱藏程序中的執行流程並使代碼混淆。但是,如果你創建容易閱讀/維護代碼,那麼這不是一個問題。
'安全'不是正確的詞。我會說可讀性較差/難以理解/難以證明是正確的。 – Steven 2010-02-08 13:40:30
這是最着名的計算機科學論文之一的主題。 Dijkstra的Go To Statement Considered Harmful。它基本上表明,沒有人需要轉到(我知道有一些例外情況一如既往)。
它是1968年,但今天仍然非常可讀。
它引發了最大的計算機科學slapfight有史以來,所以誰知道最後的結論是什麼... – Jimmy 2010-02-08 13:52:00
我的goto有着名的名字 - 如果,當,切換。 – peterchen 2010-02-08 13:52:40
本文是在一個非常不同的背景下編寫的。在那些日子裏,'goto'語句幾乎不受限制,就像在彙編代碼中一樣。也就是說,人們正在使用'goto'跳過節目中的所有地方。這相當於通過'goto'從一個函數跳到另一個函數。相比之下,C#的「goto」非常有限。這就是說,你確實沒有什麼需要。我認爲我從未在C#中遇到過碰到過「goto」是最佳選擇的案例。 – 2010-02-08 13:55:32
它是有道理的,只有向下的跳躍使得意大利麪條代碼的潛力大大降低。 (根據我的經驗,在調試遺留的基於GOTO的代碼時,75%的頭痛來自於這種情況,當向上的gotos導致混亂的循環時)
但是,考慮到你只使用向下跳轉,應該很容易轉換爲不基於代碼的代碼。我不確定有多少改進你的gotos會提供。
轉發goto的仍然是一個簡單的裝置,可以突破嵌套塊。 – peterchen 2010-02-08 13:53:41
在一個更復雜的例子中,當然如果你決定只使用GOTO來跳轉在相同的範圍,你可以使用if語句。 (如果它不在同一個範圍內,它不是真的「只是向前跳躍」,是嗎?)
(當然,如果你的真實代碼不是那麼複雜,那麼你可以擺脫那個第二塊「部分代碼...」)
好吧,這裏真的沒有問題。該代碼相當於:
Some code ...
...
if (false)
{
Some code ...
...
}
Some code ...
這就是說,我不會這樣做。 goto
的好用例非常少見,而其他流控構造在C#中更具慣用性。
現在應該避免GOTO的主要原因是程序員一般不再習慣GOTO(這是一件好事)。因此,如果您編寫廣泛使用GOTO的代碼,那麼您的同行程序員很可能難以理解並擴展它。
更糟的是,這裏和那裏的GOTO可能會導致破窗綜合症,因爲同事們開始使用越來越多的GOTO,直到您剩下一大碗意大利麪。
xkcd說得最好...
我使用goto語句時需要它JUMB從向下許多地方的代碼塊。通常沒有goto語句,這可能需要編寫另一個函數(以便上面的代碼塊在第一個函數中不重複)並在第一個函數內部調用。 goto的效率不及if或switch語句,因爲它還利用if,switch等使用的jumb語句之一(jz,jnz等)。
有了這個評論,我不鼓勵使用的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);
}
您將不得不對此進行擴展。目前還不清楚你的意思。一些示例代碼可能會有所幫助。 – 2010-02-08 13:37:52
有多少GOTO問題會導致SO內爆? – 2010-02-08 13:42:23
安全性在這裏不是問題。質量和可讀性是。 – 2010-02-08 13:48:03