OurJS


OurJS-我们的JS, 我们的技术-IT文摘; 专注JS相关领域;
我们热爱编程, 我们热爱技术;我们是高大上, 有品味的码农;

欢迎您订阅我们的技术周刊


我们会向您分享我们精心收集整理的,最新的行业资讯,技术动态,外文翻译,热点文章;
我们使用第三方邮件列表向您推送,我们不保存您的任何个人资料,注重您的隐私,您可以随时退订,

欢迎分享您的观点,经验,技巧,心得

让我们一起找寻程序员的快乐,探索技术, 发现IT人生的乐趣;


本网站使用缓存技术每次加载仅需很小流量, 可在手机中流畅浏览;
如果您发现任何BUG,请即时告知我们: ourjs(at)ourjs.com

为什么大神级程序员的C语言代码里到处都是goto?


分享到
分类 心得体会   发布 ourjs  1389234155000
注意 转载须保留原文链接,译文链接,作者译者等信息。  
当我学C语言时,老师整天告诉我:“不要使用goto, 这是一个坏习惯, 这种写法很烂,而且很危险!”等等。

但是为什么那么多内核程序员那么喜欢用goto呢?在这段linux内核  https://github.com/torvalds/linux/blob/master/kernel/sched/clock.c  代码里,我觉得可以用简单的一个while替换掉,如:

while(condition) {

}

//或

do {

} while(condition);
注*这段代码来自torvalds的linux内核代码,其实不仅可以使用while,还有很多地方可以使用if () {} else {} 的结构代替,很多内核的其他文件也是如此,如 fs.open  http://lxr.linux.no/linux+v3.12.6/fs/open.c#L464

对此我很不理解,在某些情况下使用goto比while/do-while好吗?如果是的话,为什么呢?

注: 这也许从另一个角度诠释了差点的更好Worse Is Better 的观点。

by: musicmatze

来自国外网友的精彩评论:

回答一:

对于这个例子中,我估计是从原来SMP不安全(non-SMP-safe)的方式改成SMP的方式。使用goto语句对原来的代码改动量最小,引起潜在风险的概率最小。

我其实也不赞成你们用这种方式,但我认为绝对不要使用goto也是一种误导。在一个只会向前走,绝不会后退的函数里,使用goto绝对不会引起死循环,而且这种方式绝对是最简单最清楚的跳转方式。(如通过在清理代码和返回错误时使用)

by: R..

回答二:

历史:我们也许记得Dijkstra 在1968年写的 Goto Considered Harmful http://www.u.arizona.edu/~rubinson/copyright_violations/Go_To_Considered_Harmful.html, 现在快半个世纪过去了。外面已经很少看到goto了。

不过我们来分析一下这个例子,一个关于错误处理的,让我们用结构化的语法来写:

if (do_something() != ERR) {
if (do_something2() != ERR) {
if (do_something3() != ERR) {
if (do_something4() != ERR) {
...

那么,换成goto呢?

if (do_something() == ERR)  // 一行
goto error; // |
if (do_something2() == ERR) // |
goto error; // |
if (do_something3() == ERR) // |
goto error; // V
if (do_something4() == ERR) // 使用普通的平铺形式
goto error;

我们看到这段代码都是平级的,不相互依辣的,明显goto的结构更好。

by: Dietrich Epp

来自国内网友的精彩评论

夜晚的风雪 2014-01-09 21:04
一 句话解释“写汇编写惯了”。对于写应用程序的人来说,if,while自然是熟悉的不能再熟悉,但是系统程序员不同,由于要和硬件打交道比较多,经常写汇 编。尤其对于某些大神而言,可能用汇编还习惯些,比如早期的linux内核代码有大量的汇编。汇编里面没有所谓的if,while,基本上就是无条件和有 条件跳转。所以用熟了,习惯使然吧。


刘江总编 2014-01-09 16:05
其实goto语句的问题,在《代码大全》(Code Complete)一书中有17.3专门一节详细讲述支持(以Knuth大神为首)和反对(以Dijkstra大神为首)两方的观点。最后作者本人的结论 是:90%情况下用goto都是错的,但少数情况goto确实有效(比如在错误处理中的多重判断,又如两个条件判断和一个else子句的情况),是解决问 题的合理办法。这时候用goto无妨,但应该加注释说明理由。 查到这一节英文网上有:http://www.stevemcconnell.com/ccgoto.htm



原文地址: 点此
社区评论 ( Beta版 )
  • #0 sinchb 1389274557000
    if (do_something() == ERR) return error(); if (do_something2() == ERR) return error(); if (do_something3() == ERR) return error(); if (do_something4() == ERR) return error(); 不也是平铺形式。。。。
  • #1 温柔 1389311688000
    goto 代价小,速度快被你吃了? 如果你对代码了然于心,请用goto, 如果接管你代码的人比你差,请别用,估计他会拿砖头到你家拜访~
  • #2 knull 1389313591000
    我个人体会:我没用过goto,主要是敬畏。见过goto,主要是异常处理的时候。我觉得,不是goto不好,而是我们不够水平:goto很难用,一不小心,就是挂了。就像指针,虽然很好用,但是越来越少用了。goto也许比指针更难用。
  • #3 一二 1389314816000
    @sinchb

    if(do_something() == ERR){ free(something1); return error(); } if(do_something2() == ERR){ free(something1); free(something2); return error(); } if(do_something3() == ERR){ free(something1); free(something2); free(something3); return error(); } ~ }
  • #4 瑶冰魄 1389316615000
    之前看《IP/TCP详解》卷二源代码,几乎每个函数都用goto语句跳到错误处理。
  • #5 爱还逝 1389316968000
    do { if (do_something() == ERR) // break; // | if (do_something2() == ERR) // | break; // | if (do_something3() == ERR) // | break; // V if (do_something4() == ERR) // 使用普通的平铺形式 break; }while(0);
  • #6 粉末 1389331366000
    @sinchb

    一看这个就知道没写过C的,出错了东西要释放怎么办?
  • #7 hax 1389333145000
    以前goto的问题主要是乱跳。如果限制了scope只在本函数内,用下goto其实没什么问题。
  • #8 李朝 1389605012000
    @粉末

    可以在error函数里释放啊!
  • #9 book_withc 1390295769000
    @爱还逝

    break只是跳出循环而已,不能跳到错误处理的地方。goto的目的是说,如果没有错误,就一直往下执行代码,如果有错就跳到函数结尾的地方进行错误处理。
  • #10 张齱牚 1392193833000
    [/流汗]
  • #11 Einstein.Light 1407920768609

    goto语句会让结构更加清晰简洁,乱跳只是运用不当.

  • #12 szwork2013 1407928362304

    不错。。

  • #13 元兄记 1445147120761

    因为所谓的“少用goto“的根本逻辑本来就是会增加阅读难度啊,不是goto不好,是照顾阅读者水平。大神级的水平,当然可以轻松驾驭。

  • #14 宁丈北 1471579389225

    。。。。。。。。

  • #15 叶末关 1478530408228

    goto 完全可以代替while ,do while,for, switch 啊

  • #16 叶末关 1478530574508

    最简单来说,写一个死循环用 goto效率比while (1)高吧。

  • #17 司千奶 1488783868763

    从可维护性的角度而言,少用goto没什么错。否则用多了容易破坏代码的结构性,读起来尿急

  • #18 白而无 1497401702997

    @温柔 #1

    这么说不对,可读性也很重要,毕竟开发成本是存在的,谁也不想被阴一下,这种说法可以理解的,是吧

  • #19 区叹东 1502118309656

    @sinchb #0

    vv

  • #20 区叹东 1502118397117

    有时候,使用goto要省不少事,还简单

  • #21 陆叨也 1505258236539

    一般用在处理一些比较严重得错误的时候,不想变成堆雪球的效果吧

OnceDoc 您自己的企业内容管理系统——文档、流程、知识库、报表、网盘All In One

访问404页面,寻找丢失儿童
 热门文章 - 分享最多
  1. 一名靠谱的JavaScript程序员应备的素质
  2. PayPal为什么从Java迁移到Node.js,性能提高一倍,文件代码减少44%
  3. 微软,请不要使用 Try/Catch
  4. 人类只占到互联网流量的40%不到
  5. 人们为什么不使用Python3?
  6. 如何面试前端工程师:Github很重要
  7. 芝加哥将计算机科学列为主修课
  8. 为什么大神级程序员的C语言代码里到处都是goto?
  9. 我为什么想把比特币一把火烧了
  10. 钱,花对地方了吗?一则工程师的故事
  11. AirJD-简单好用的免费建站工具

 相关阅读 - 心得体会
  1. 微软,请不要使用 Try/Catch
  2. 人们为什么不使用Python3?
  3. 代码不等于计算机科学:为什么所有人都应该学习编程
  4. 一名靠谱的JavaScript程序员应备的素质
  5. 程序员最艰巨的十大任务
  6. 世界上最优秀的程序员同时也是活得最快乐的人
  7. 做从未被做过的事:偶遇 Russell Kirsch
  8. 他们为什么说面向对象有问题,探讨面向对象的一些缺陷
  9. 入静和入世
  10. 信仰是如何毁掉程序员的

 欢迎订阅 - 技术周刊

我们热爱编程, 我们热爱技术; 我们是高端, 大气, 上档次, 有品味, 时刻需要和国际接轨的码农; 欢迎您订阅我们的技术周刊; 您只需要在右上角输入您的邮箱即可; 我们注重您的隐私,您可以随时退订.
加入我们吧! 让我们一起找寻码农的快乐,探索技术, 发现IT人生的乐趣;


 关注我们

我们的微信公众号: ourjs-com
打开微信扫一扫即可关注我们:
IT文摘-程序员(码农)技术周刊

ourjs官方微信号