問題描述
在本主題中,我們將研究 goto
在 C 或 C++ 中的良好使用示例.它的靈感來自一個人們投票贊成的答案,因為他們以為我在開玩笑.
In this thread, we look at examples of good uses of goto
in C or C++. It's inspired by an answer which people voted up because they thought I was joking.
總結(標簽從原來的改變使意圖更加清晰):
Summary (label changed from original to make intent even clearer):
infinite_loop:
// code goes here
goto infinite_loop;
為什么它比替代方案更好:
Why it's better than the alternatives:
- 這是具體的.
goto
是語言結構導致無條件分支.備擇方案依賴于使用結構支持條件分支,帶有退化的永遠真實條件. - 標簽記錄意圖沒有額外的評論.
- 讀者無需掃描早期
break
的干預代碼(雖然仍然有可能無原則的黑客來模擬continue
使用早期的goto
).
- It's specific.
goto
is the language construct which causes an unconditional branch. Alternatives depend on using structures supporting conditional branches, with a degenerate always-true condition. - The label documents the intent without extra comments.
- The reader doesn't have to scan the
intervening code for early
break
s (although it's still possible for an unprincipled hacker to simulatecontinue
with an earlygoto
).
規則:
- 假裝沒有恐懼癥贏.據了解,上述不能在實際代碼中使用,因為它違背了既定的習語.
- 假設我們都聽說過后藤被認為有害"并知道goto 可以用來寫意大利面代碼.
- 如果你不同意一個例子,批評它的技術價值獨自一人('因為人們不喜歡goto' 不是技術原因).
讓我們看看我們是否可以像大人一樣談論這個.
Let's see if we can talk about this like grown ups.
編輯
這個問題現在似乎已經結束了.它產生了一些高質量的答案.謝謝大家,尤其是那些認真對待我的小循環示例的人.大多數懷疑論者擔心由于缺少塊作用域.正如@quinmars 在評論中指出的那樣,您始終可以在循環體.我注意到 for(;;)
和 while(true)
沒有給你大括號免費(并且省略它們會導致令人煩惱的錯誤).反正我不會再浪費了你在這件小事上的腦力 - 我可以忍受無害和慣用的 for(;;)
和 while(true)
(如果我想保持我的工作).
This question seems finished now. It generated some high quality answers. Thanks to everyone,
especially those who took my little loop example seriously. Most skeptics were concerned
by the lack of block scope. As @quinmars pointed out in a comment, you can always put braces around the
loop body. I note in passing that for(;;)
and while(true)
don't give you the braces
for free either (and omitting them can cause vexing bugs). Anyway, I won't waste any more
of your brain power on this trifle - I can live with the harmless and idiomatic for(;;)
and while(true)
(just as well if I want to keep my job).
考慮到其他回復,我看到很多人都將 goto
視為您一直以來的事情必須以另一種方式重寫.當然,您可以通過引入循環來避免 goto
,一個額外的標志,一堆嵌套的 if
s,或者其他什么,但為什么不考慮 goto
是否是也許是這項工作的最佳工具?換句話說,為了避免將內置語言功能用于其預期目的,人們準備忍受多少丑陋?我的看法是甚至增加一面旗幟也付出了過高的代價.我喜歡我的變量來表示事物問題或解決方案域.'僅僅為了避免 goto
' 并不能解決問題.
Considering the other responses, I see that many people view goto
as something you always
have to rewrite in another way. Of course you can avoid a goto
by introducing a loop,
an extra flag, a stack of nested if
s, or whatever, but why not consider whether goto
is
perhaps the best tool for the job? Put another way, how much ugliness are people prepared to endure to avoid using a built-in language feature for its intended purpose? My take is that
even adding a flag is too high a price to pay. I like my variables to represent things in
the problem or solution domains. 'Solely to avoid a goto
' doesn't cut it.
我會接受第一個答案,它給出了分支到清理塊的 C 模式.IMO,這當然是所有已發布答案的 goto
的最強案例如果你用仇恨者為了避免它而必須經歷的扭曲來衡量它.
I'll accept the first answer which gave the C pattern for branching to a cleanup block. IMO, this makes the strongest case for a goto
of all the posted answers, certainly
if you measure it by the contortions a hater has to go through to avoid it.
推薦答案
這是我聽說人們使用的一個技巧.不過我從來沒有在野外見過它.它只適用于 C,因為 C++ 有 RAII 可以更慣用地做到這一點.
Heres one trick I've heard of people using. I've never seen it in the wild though. And it only applies to C because C++ has RAII to do this more idiomatically.
void foo()
{
if (!doA())
goto exit;
if (!doB())
goto cleanupA;
if (!doC())
goto cleanupB;
/* everything has succeeded */
return;
cleanupB:
undoB();
cleanupA:
undoA();
exit:
return;
}
這篇關于C 或 C++ 中好的 goto 示例的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!