怎么看待 C 或者 C++里面的 goto 语句

2020-03-01 14:14:40 +08:00
 cjw1115

很多人和书籍都建议不要使用 goto 语句,说他打乱程序的执行流程,使得程序难以理解。

但是在微软的很多实践里面,有大量的地方用到了 goto 语句,比如我常常接触的 Windows 声音处理技术里面,微软 的很多代码都在使用 goto .

举个例子, 感觉第二种的确是比较舒服

HRESULT demo()
{
    auto hr = Interface1();
    if( hr != S_OK)
    {
        //error processing
        ....
        return hr;
    }
    ......
    hr = Interface3();
    if( hr != S_OK)
    {
        //error processing
        ....
        return hr;
    }
    ......
    return hr;
}

HRESULT demo()
{
    auto hr = Interface1();
    if(hr != S_OK)
    {
        goto ERROR;
    }
    ......
    hr = Interfacen();
    if(hr != S_OK)
    {
        goto ERROR;
    }
    
    return hr;
ERROR:
    //error processing
    ....
    return hr;
}

你们怎么看

2634 次点击
所在节点    问与答
21 条回复
codehz
2020-03-01 14:23:15 +08:00
(不是因为 API 是面向 C 的,不适合用异常机制处理(以及很多场景用不了),然后写一大堆 if 也很反人类的妥协之举么
Crimilals
2020-03-01 14:23:55 +08:00
jmp 与 ret 的区别,看个人喜好
aheadlead
2020-03-01 14:24:15 +08:00
其实用得好没问题的,linux kernel 里 goto 也挺多的
nicevar
2020-03-01 14:26:14 +08:00
不建议滥用,不是不让用,自己的程序不怕以后看不懂 goto 出来个蜘蛛网都没人管你
cabing
2020-03-01 14:29:54 +08:00
go 其实用的挺多的。
cabing
2020-03-01 14:30:30 +08:00
类似 got 的用法,一般都是 break loop
xiadong1994
2020-03-01 17:59:32 +08:00
goto 用在错误处理很好用的,尤其是一个函数有好几个可能出错的位置的时候,更高级的语言都用 exception 了。
lcdtyph
2020-03-01 18:00:43 +08:00
你如果写驱动就知道了…不用 goto 是很难受的
linux 源码里也有大量的 goto
inhzus
2020-03-01 18:02:16 +08:00
错误处理,跳出循环等等还是有使用场景的,我觉得只要不滥用,逻辑很清晰就好
catror
2020-03-01 18:07:15 +08:00
不是不用,是不要滥用
optional
2020-03-01 18:08:47 +08:00
c 里面没有 break 2; 这种语法用来 break 嵌套循环,这时候不用 goto 反而遭罪。
kneep
2020-03-01 18:28:51 +08:00
异常退出时清理资源,linux 里面很多,如果不用 goto,反而不清晰。其实不必过分担心。
Buges
2020-03-01 18:32:15 +08:00
错误重试,异常处理,跳出多重循环都很有用。因为好用所以容易滥用,但也不能因噎废食完全不给用。
ybw
2020-03-01 18:34:25 +08:00
我用 goto 语句的变相形式,do while(0)。但是绝不直接使用 goto
cmdOptionKana
2020-03-01 18:49:45 +08:00
三年前

尹志平问:“大师兄,你为什么用这招,师父不是说这是禁招吗?”

大师兄没有回答,尹志平也一直紧遵师命不敢使用禁招,有时他也看到有人因为使用这招反而伤了自己。

三年后的一个雨夜,尹志平受奸人所害,陷入重围,寡不敌众。就在命悬一线之时,他猛然想起大师兄使出禁招的那一幕……

尹志平暴喝一声:“大师兄,我懂了!!!”,剑招一变,身法突然诡异起来,围攻他的众人一时不备,纷纷受伤,其中一人被直穿心脏,另一人竟心生退意,怪叫一声逃了。其余人等见今日之事不可成,作鸟兽散。

尹志平持剑巍然立于雨中,口中轻声说道:原来我师门剑招之精妙尽在禁招之中……
kkk330
2020-03-01 19:09:25 +08:00
单独链接发不出来, 就这样吧, sm.ms/image/FgiaOqfzctvu6WZ
emon100
2020-03-01 19:16:35 +08:00
2 月我花了 15 天翻译了一篇文章《重新审视 <GOTO 语句被认为有害>》。里面有 Dijkstra 《 Go to 语句被认为有害》的原文,还有相关历史和评价,想详细了解的话可以看看。

Dijkstra 的原话如下:
“现在的 go to 语句太原始了;太多地把程序弄得一团糟。如果控制 go to 的使用,它还是可以被考虑使用并被欣赏的。
...
go to 语句不合需要的说法并非新鲜事物。我记得读过明确的建议,建议上明确推荐只将 go to 用在警报时的退出 (alarm exit),但是我无法查到在哪。”

这里 alarm exit 就是现在常说的抛异常,原文中 Dijkstra 的意思是,当编程语言没有如异常处理机制之类的设施时,goto 是可以被用作提高程序表现力的。

《重新审视 <GOTO 语句被认为有害>》的链接: https://www.emon100.me/goto-translation/
我的译后感: https://blog.emon100.me/2020/02/10/%E7%BF%BB%E8%AF%91%E3%80%8A%E9%87%8D%E6%96%B0%E5%AE%A1%E8%A7%86-GOTO-%E8%AF%AD%E5%8F%A5%E8%A2%AB%E8%AE%A4%E4%B8%BA%E6%9C%89%E5%AE%B3-%E3%80%8B%E7%9A%84%E6%84%9F%E6%83%B3/
caowentao
2020-03-01 20:32:20 +08:00
目前 goto 典型的应用场景就是错误处理,因为出现错误要即时停止当前流程,这正好符合 goto 打乱程序流程的特性。其他场景尽量选择结构语句来实现。goto 打乱程序流程指的是应该使用结构语句的地方,确用 goto 生造逻辑结构,导致程序混乱。
turi
2020-03-01 20:51:05 +08:00
从来没用过
icyalala
2020-03-02 01:04:29 +08:00
有限状态机也是一个非常合适的场景

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/648820

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX