`
cloudtech
  • 浏览: 4593648 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

如何写优雅的代码(1)——灵活使用goto和__try

 
阅读更多

//========================================================================
//TITLE:
// 如何写优雅的代码(1)——灵活使用goto和__try
//AUTHOR:
// norains
//DATE:
// Thursday 16-July-2009
//Environment:
// WINCE5.0 + VS2005
//========================================================================

goto是毒药?凡是能用goto的地方,肯定能用结构化方式来实现相同的目的!估计很多朋友都对这论断不会陌生,甚至可以说,太熟悉了!但能实现并不代表优雅。不信?我们接下来看看。

假设我们有一个函数,需要实现如下功能:将一个驱动某些内容读取到缓存区去;又因为该缓存是全局公用的,所以我们很自然采用互斥量来进行控制。首先,我们坚持采用结构化方式实现,很可能我们的代码类似如下:

没错,采用这种结构化的方式的确是解决了问题。可是,我们是不是有点别扭呢?每次出错,返回FALSE之前,都必须要清理一次资源。小函数也许还不是什么大问题,只要睁大眼睛,小心翼翼,还是能在后续的返回中正确处理资源释放的。但如果函数因为要加入某些功能越来越大,又或许是别人来维护这段代码,那能保证在返回前释放资源么?


接下来我们使用被大家鄙弃的goto,看看会发生什么情形:

怎么样?把所有的资源释放都放到EXIT段中,每个EnterCriticalSection都能对应一个LeaveCriticalSection,是不是显得比之前的更为优雅?还能说goto为鸡肋么?

不过,goto也不是尽善尽美,比如变量dwSize在goto之后就不能初始化,只能将局部变量的初始化放到第一个goto之前。按照C++的建议,变量的声明最好尽可能接近使用的地方。而放在第一个goto之前,摆明就是C作风嘛!

其实如果以本特例,直接声明dwSize而不进行初始化也是可行的;但这并不代表在别的情况下也能畅通无阻,也许有的程序就依赖于初始化的值,谁知道呢?


那有没有更为优雅的?可以解决这dwSize的位置问题的?答案自然是肯定的。不过,就必须请我们的__try出场咯:

哦耶!现在dwSize终于在它该出现的位置上了,是不是显得比goto更为优雅呢?

这段改写的代码采用的是SEH机制。因为SEH机制如果需要详细解释,就不是一言两语的事情,所以在此就略过,感兴趣的朋友可以自己在网上查找资料。在这里,只是说明一点,采用SEH机制,无论如何,最后基本上一定要运行__finally段代码,除非中间有中断。


最后一段是不是意味着凡是可以运用goto的地方都能采用__try替代?答案是否定的。特别是代码中采用了STL,SEH机制将会无能为力。

不信?我们添加一点代码段来看看事情的真相。假设我们不是通过数组来保留缓存,而是保留于STL的vector中,并且成功读取之后,我们还想输出每个数值,那么我们代码可以如下:


很遗憾,这段代码无法编译通过。因为STL的迭代器中用到了对象,而对象会释放C++异常,而这和SEH有冲突。当然,我们完全可以用new来替代,以避开这个问题,但这样一来,却是使代码更峥嵘,离优雅更是八辈子打不到一个杆子上。

这时候,还是只能用goto:

最后这个例子,从另一个角度说明了,goto并不一定是鸡肋,在某些特定的环境下,只有它才能拯救代码于优雅之境地。

分享到:
评论

相关推荐

    c++中的goto(csdn)————程序.pdf

    c++中的goto(csdn)————程序

    课程设计实验——八皇后_VC++游戏

     (a)为解决这个问题,我们把棋盘的横坐标定为i,纵坐标定为j,i和j的取值范围是从1到8。当某个皇后占了位置(i,j)时,在这个位置的垂直方向、水平方向和斜线方向都不能再放其它皇后了。用语句实现,可定义如下三...

    编译原理——词法分析代码

    ⒈ 题目 编写前述PASCAL子集的词法分析程序。 1)主程序设计考虑,(参阅后面给出的程序框架) 主程序的说明部分为各种表格和变量安排空间。 数组k为关键字表,每个数组元素存放一个关键字。...GOTO 1 END.

    SLR(1).rar_SLR(1) 表 C++_SLR(1)文法C++_SLR(1)的GOTO_action表和goto表_sl

    SLR(1)分析表分析法,给出一个分析表含action和goto表,然后对给出的语句进行语法分析,规约判断!

    VBA 一句代码解决On error goto line 多次使用的问题 .txt

    一句代码解决On error goto line 多次使用的问题 .txt On error goto line 错误跳转语句只能使用一次 本代码只需要加一句即可重复使用错误跳转 On error goto line VBA错误跳转多次使用的问题 On error goto 0 ...

    goto解密程序php源码,直接上传即可解密goto加密的代码

    php goto解密源码,无需数据库,直接上传即可使用。亲测可解php的goto加密方式

    易语言Goto例程1源码,易语言Goto例程2源码,易语言Goto应用实例:

    易语言Goto跳转模块源码,Goto跳转模块,Goto,GetGotoAddr,FillMemory,CopyMemory,GetModuleFileNameEx,IsBadReadPtr,Goto测试_1,Goto测试_2,测试子程序,循环子程序,SHCreateDirectory

    vb写的一个小解释器 推荐

    这是我在2010年空闲时间写出来的一个小脚本解释的程序,一直没做介绍及工程打包发布,现在简单说明下。这个小程序语言简洁,已经能实现if和循环,已经可以做很多事了。 【语法介绍】 语法很简单赋值和一般的程序...

    goto for python模块:在Python中支持goto

    作者说是个愚人节诞生的作品,还郑重表示不要使用它。不过,偶尔还是可以拿来测试一下代码用。 模块安装方法:python setup.py install 使用方法: from goto import goto, label for i in range(1, 10): for j in...

    IDL基本语法_idlgoto语句_IDL中goto语句_IDL基本语法_

    IDL break、continue、goto等基本语法的使用例子,可学习idl

    goto_sel_ide.js

    1.添加js扩展 2.扩展添加完成后重启ide,便能选择whiile等命令,例: Commend Target Value store 1 x while $(x) echo Value of x is $x storeEval new Number(storedVars['x'])+1 x endWhile 3.将录制的内容添加...

    ACE_OS::mktime函数源代码

    if ( (tmptm1 < _BASE_YEAR - 1) || (tmptm1 > _MAX_YEAR64 + 1) ) goto err_mktime; } /***** HERE: tmptm1 holds number of elapsed years *****/ /* * Calculate days elapsed minus one, in the given ...

    C语言模拟实现 try catch

    在C语言中,使用goto和标签的方式模拟try catch的功能,使用setjmp和longjmp方式模拟try catch的功能,两种方式都可以使用,setjmp的方式可以支持try catch嵌套,goto的方式不支持嵌套,但是jmpbuf的开销是比较大的...

    break_continue_goto_return语句

    break_continue_goto_return语句

    SVN提交时强制添加注释

    —————————————————————————————————— 如果在windows环境中,则命名为pre-commit.bat并将该文件放在创建的库文件的hooks文件中 ————————————————————————...

    C#全能速查宝典

    1.1.9 迭代器——相同类型的值的有序序列的一段代码 10 1.1.10 泛型——处理算法和数据结构 11 1.1.11 分部类——将一个类分成几部分 12 1.1.12 is操作符——检查变量是否为指定的类型 14 1.1.13 lock关键字——锁定...

    使用python画出一个懒羊羊代码(附详细注释)全

    示例代码使用了Turtle库来实现绘图功能,通过调用不同的函数和方法来绘制懒羊羊的头部、身体、眼睛、腿和尾巴等部分。你可以根据自己的喜好调整懒羊羊的位置、大小和颜色等。 希望这个示例能够为你提供一些关于使用...

    OK血糖仪部分汇编代码

    显示LO和温度计并自动关机 bsf OperateFlag,temp_lo goto MeasureTemperEnd CheckHighLimit: movlw 01h subwf TempValueInteger,w btfss status,c goto Count_Tf btfss status,z goto TemperMax404 movlw 091h ;191...

    Goto文件搜索

    1、UI库 UI库时使用WTL为基础架构的充分考虑自绘和无窗口模式设计开发的,同时兼顾两者使用,Goto由于关注的是搜索功能,所以使用前面的设计,因为开发库是要很长时间的,个人短时间很难完成。 2、XLib库,主要是...

Global site tag (gtag.js) - Google Analytics