C++ goto用法
作者:梨梨喵
链接: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用法相关推荐
- python goto 用法
python goto 用法 pip install goto-statement from goto import with_goto @with_goto def range(start, sto ...
- loop和goto用法
loop和goto用法 之所以写这个博客是因为,我在csDN查loop时搜到的文章都要money ,或者积分,但我不想消耗积分在这上面.
- python中goto的用法,python goto用法 基于python goto的正确用法说明
想了解基于python goto的正确用法说明的相关内容吗,追梦小狂魔在本文为您仔细讲解python goto用法的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:python,goto用法 ...
- c语言goto语句标号作用,goto语句怎么用(c语言goto用法)
goto语句怎么用(c语言goto用法) 2020-07-28 02:03:29 共10个回答 1.C语言中goto又叫无条件转移语句,可以让程序直接跳转到任意标记的位置.用法就是"goto ...
- php goto call,Php中的goto用法
我们先举个简单示例: goto LABEL; //这个标签自定义 echo '乔峰'; LABEL: echo '鸠摩智'; 以上例程会输出:鸠摩智 解释: goto 操作符可以用来跳转到程序中的另一 ...
- java中goto用法源代码,java中goto语句解析12
hi, 今天无意中看到有个兄弟在java程序中多次用到了goto语句,感觉很是怪异,copy来编译下发现有很多错误! 为此,我付出了一下午时间去研究这个块被人遗忘了的可怕的"魔鬼" ...
- C# goto用法事例
static void Main(string[] args) { goto tag1; System.Console.Write ...
- Java中goto用法
臭名昭著的goto 第一次见到goto应该在<C programming>这本书里,那是相当地震惊:想起之前从循环深处往出跳的那个费劲. 废话不多说,咱这里先用上感受一下: /* 一个整数 ...
- oracle goto用法
oracle中goto一般用在循环当中.作用类似于continue,看下面代码 create or replace procedure test isi integer; begini := 0;lo ...
最新文章
- Matlab画图时的线型、标记以及颜色简记
- JavaWeb学习总结(十七)——JSP中的九个内置对象
- hdu3768 spfa+全排列
- Javascript的原型链图
- android 自动挂断,[转]android 来电自动接听和自动挂断
- 提升存储设备的吞吐量
- 常用算法大全-贪婪算法
- awstats的简单配置
- Qt QDebug 打印自定义结构体
- 杭州电子科技大学计算机技术考研总结
- Netron - 网络可视化
- nodejs爬虫获取漫威超级英雄电影海报
- Linux下Firefox安装flash操作
- SEO入门知识1:网站改版后怎么做SEO
- Android架构分析之硬件抽象层(HAL)
- 【文献心得】内存隔离技术研究现状调研
- 详解Xcode 6的视图调试
- vb如何调用计算机日历,VB日历代码.doc
- 如何用晶体管进行计算
- 【C++/C语言打印五角星----附源代码】
热门文章
- PTA(三十三)面向对象程序设计 第五章 作业 7-4 分钟秒钟的时间相减 (30 point(s))
- 《系统》是南方周末2007年度最好的特稿
- 骑士精神(双向深搜+meet in the middle)
- 人心本无染,心静自然清 ——赞“落梅”
- 【Linux】 设置支持中文 | 全局
- c语言上交源代码怎么交啊,C语言问题在线等啊作业提交上交的的内容必须由以下两个部分组成,缺 爱问知识人...
- HIT2372 Recoup Traveling Expenses(最长单调子序列)
- DSF框架使用(DAO、序列化、注解、服务接口、服务代理)
- android 4.0 bluetooth bt HFP/HSP分析
- android 语言对应