V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
cjw1115
V2EX  ›  问与答

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

  •  
  •   cjw1115 · 2020-03-01 14:14:40 +08:00 · 2853 次点击
    这是一个创建于 1758 天前的主题,其中的信息可能已经有所发展或是发生改变。

    很多人和书籍都建议不要使用 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;
    }
    

    你们怎么看

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

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

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

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

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

    尹志平持剑巍然立于雨中,口中轻声说道:原来我师门剑招之精妙尽在禁招之中……
    kkk330
        16
    kkk330  
       2020-03-01 19:09:25 +08:00   ❤️ 1
    单独链接发不出来, 就这样吧, sm.ms/image/FgiaOqfzctvu6WZ
    emon100
        17
    emon100  
       2020-03-01 19:16:35 +08:00   ❤️ 2
    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
        18
    caowentao  
       2020-03-01 20:32:20 +08:00 via iPhone
    目前 goto 典型的应用场景就是错误处理,因为出现错误要即时停止当前流程,这正好符合 goto 打乱程序流程的特性。其他场景尽量选择结构语句来实现。goto 打乱程序流程指的是应该使用结构语句的地方,确用 goto 生造逻辑结构,导致程序混乱。
    turi
        19
    turi  
       2020-03-01 20:51:05 +08:00
    从来没用过
    icyalala
        20
    icyalala  
       2020-03-02 01:04:29 +08:00 via iPhone
    有限状态机也是一个非常合适的场景
    qakito
        21
    qakito  
       2020-03-02 09:14:32 +08:00
    C 里用得比较多,现代 C++应该都采用 exception 了吧
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1027 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 19:47 · PVG 03:47 · LAX 11:47 · JFK 14:47
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.