作者:梨梨喵
链接:https://www.zhihu.com/question/27922046/answer/73347171
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

关于goto的使用, 一个是跳出多层循环时使用, 还有一个是在性能考虑. 其他场景下基本上没有goto什么事, 特别在现代C++的情况下.我的个人结论是除非是非goto不可的情况下绝不使用goto. 喜欢用goto说明姿势水平还不够高, 没有找到能很好描述逻辑的方式和工具, 还需要学习一个.之前在读源码的时候也发现了一些使用goto情况, 如@蓝色说的统一的错误处理情况和统一的资源管理的情况. 不过在有了C++11 lambda后goto存在的意义就不大了, 统一的错误处理和资源管理可以交给RAII+lambda.如有以下一情况:

HANDLE func()
{HANDLE h = CreateSomeObject(...);//...if(error0_occur){goto err_exit;}//...if(error1_occur){goto err_exit;}//...return h;
err_exit:CloseHandle(h);return nullptr;
}

在有了C++11 lambda后, 可以交给RAII来管理了, goto在这种情景下使用的意义并不大了

class ScopeGuard
{public:explicit ScopeGuard(std::function<void()> onExit): __onExit(onExit), __dismissed(false){ }~ScopeGuard(){if (!__dismissed){__onExit();}}void Dismiss(bool dismissed=true){__dismissed = dismissed;}ScopeGuard(ScopeGuard const&) = delete;ScopeGuard& operator=(ScopeGuard const&) = delete;// non-copyableprivate:std::function<void()> __onExit;bool __dismissed;
};HANDLE func()
{HANDLE h = CreateSomeObject(...);ScopeGuard onErrorExit([&] { CloseHandle(h); h=nullptr; });//...if(error0_occur){return nullptr;}//...if(error1_occur){return nullptr;}//...onErrorExit.Dismiss()  // no error occurreturn h;
}

另一点, 在关于性能方面goto在VM上有一定作用如一个简单的指令循环如下:

while (byte_code.size()>IP)
{switch (byte_code[IP]){case BYTE_CODE::INSTRUCTION_0:{//some action for instruction 0IP += sizeof(instruction_0);break;}case BYTE_CODE::INSTRUCTION_1:{//some action for instruction 1IP += sizeof(instruction_1);break;}case BYTE_CODE::INSTRUCTION_2:{//some action for instruction 2IP += sizeof(instruction_2);break;}//...//more cases}
}

这么写的话在switch和while上出现了至少两个分支语句, 一次指令循环中要进行一次条件跳转和三次无条件跳转(开启switch跳转表优化后)在使用goto语句后可以大大减少在这些控制语句上的性能消耗, 配合GCC的拓展Labels as Values使用.

static const void *next_instr[] = { &&byte_code_halt,&&byte_code_instr0,&&byte_code_instr1,&&byte_code_instr2,//...
}switch (byte_code[IP])  //for initial instruction
{case BYTE_CODE::HALT:  //end of loop
{byte_code_halt:break;
}
case BYTE_CODE::INSTRUCTION_0:
{byte_code_instr0://some action for instruction 0IP += sizeof(instruction_0);goto *(next_instr[byte_code[IP]]);
}
case BYTE_CODE::INSTRUCTION_1:
{byte_code_instr1://some action for instruction 1IP += sizeof(instruction_1);goto *(next_instr[byte_code[IP]]);
}
case BYTE_CODE::INSTRUCTION_2:
{byte_code_instr2://some action for instruction 2IP += sizeof(instruction_2);goto *(next_instr[byte_code[IP]]);
}//...
//more cases}

在指令流结束的位置插入一条halt指令表示终止. 这样就一次指令循环中只有一次无条件跳转. 性能上能获得一定的提高.之前在我自己写VM的时候做profile, 发现在switch和while上至少消耗了12%的性能, 改用goto后获得了7%的性能的提升.在这一点上goto还是有一定的意义的.

「C++11」Lambda 表达式

C++ goto用法相关推荐

  1. python goto 用法

    python goto 用法 pip install goto-statement from goto import with_goto @with_goto def range(start, sto ...

  2. loop和goto用法

    loop和goto用法 之所以写这个博客是因为,我在csDN查loop时搜到的文章都要money ,或者积分,但我不想消耗积分在这上面.

  3. python中goto的用法,python goto用法 基于python goto的正确用法说明

    想了解基于python goto的正确用法说明的相关内容吗,追梦小狂魔在本文为您仔细讲解python goto用法的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:python,goto用法 ...

  4. c语言goto语句标号作用,goto语句怎么用(c语言goto用法)

    goto语句怎么用(c语言goto用法) 2020-07-28 02:03:29 共10个回答 1.C语言中goto又叫无条件转移语句,可以让程序直接跳转到任意标记的位置.用法就是"goto ...

  5. php goto call,Php中的goto用法

    我们先举个简单示例: goto LABEL; //这个标签自定义 echo '乔峰'; LABEL: echo '鸠摩智'; 以上例程会输出:鸠摩智 解释: goto 操作符可以用来跳转到程序中的另一 ...

  6. java中goto用法源代码,java中goto语句解析12

    hi, 今天无意中看到有个兄弟在java程序中多次用到了goto语句,感觉很是怪异,copy来编译下发现有很多错误! 为此,我付出了一下午时间去研究这个块被人遗忘了的可怕的"魔鬼" ...

  7. C# goto用法事例

    static void Main(string[] args)         {             goto tag1;                System.Console.Write ...

  8. Java中goto用法

    臭名昭著的goto 第一次见到goto应该在<C programming>这本书里,那是相当地震惊:想起之前从循环深处往出跳的那个费劲. 废话不多说,咱这里先用上感受一下: /* 一个整数 ...

  9. oracle goto用法

    oracle中goto一般用在循环当中.作用类似于continue,看下面代码 create or replace procedure test isi integer; begini := 0;lo ...

最新文章

  1. Matlab画图时的线型、标记以及颜色简记
  2. JavaWeb学习总结(十七)——JSP中的九个内置对象
  3. hdu3768 spfa+全排列
  4. Javascript的原型链图
  5. android 自动挂断,[转]android 来电自动接听和自动挂断
  6. 提升存储设备的吞吐量
  7. 常用算法大全-贪婪算法
  8. awstats的简单配置
  9. Qt QDebug 打印自定义结构体
  10. 杭州电子科技大学计算机技术考研总结
  11. Netron - 网络可视化
  12. nodejs爬虫获取漫威超级英雄电影海报
  13. Linux下Firefox安装flash操作
  14. SEO入门知识1:网站改版后怎么做SEO
  15. Android架构分析之硬件抽象层(HAL)
  16. 【文献心得】内存隔离技术研究现状调研
  17. 详解Xcode 6的视图调试
  18. vb如何调用计算机日历,VB日历代码.doc
  19. 如何用晶体管进行计算
  20. 【C++/C语言打印五角星----附源代码】

热门文章

  1. PTA(三十三)面向对象程序设计 第五章 作业 7-4 分钟秒钟的时间相减 (30 point(s))
  2. 《系统》是南方周末2007年度最好的特稿
  3. 骑士精神(双向深搜+meet in the middle)
  4. 人心本无染,心静自然清 ——赞“落梅”
  5. 【Linux】 设置支持中文 | 全局
  6. c语言上交源代码怎么交啊,C语言问题在线等啊作业提交上交的的内容必须由以下两个部分组成,缺 爱问知识人...
  7. HIT2372 Recoup Traveling Expenses(最长单调子序列)
  8. DSF框架使用(DAO、序列化、注解、服务接口、服务代理)
  9. android 4.0 bluetooth bt HFP/HSP分析
  10. android 语言对应