C 或 C++ 中好的 goto 示例
在本主题中,我们将研究 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;
}
相关文章