用goto做异常处理
今天在CSDN上看到的关于错误返回值的讨论,感觉非常有趣。 从中可以看出被教化的孩子与大神之间的区别...
讨论如下: 先放上提问者的源程序: 这是第一种,做出判断后,如果条件出错,直接return......
1 int mystrlen(char *str) 2 { 3 int count = 0; 4 if (str == NULL) 5 { 6 return -1; 7 } 8 9 if (*str == 0) 10 { 11 return 0; 12 } 13 14 while(*str != 0 ) 15 { 16 count++; 17 str++; 18 } 19 return count; 20 }
这是第二种,先设置一个变量,对变量赋值,只有一个return.....
1 int mystrlen(char *str) 2 { 3 int ret; 4 if (str == NULL) 5 { 6 ret = -1; 7 } 8 else if (*str == 0) 9 { 10 ret = 0; 11 } 12 else 13 { 14 ret = 0; 15 while(*str != 0 ) 16 { 17 ret++; 18 str++; 19 } 20 } 21 return ret; 22 }
这是第三种,使用goto语句:
1 int mystrlen(char *str) 2 { 3 int ret; 4 if (str == NULL) 5 { 6 ret = -1; 7 goto _RET; 8 } 9 10 if (*str == 0) 11 { 12 ret = 0; 13 goto _RET; 14 } 15 16 17 while(*str !=0 ) 18 { 19 ret++; 20 str++; 21 } 22 23 _RET: 24 return ret; 25 }
就这三种返回方式作出了激烈讨论!
从小孩子的观点来看,我们不应该使用GOTO语句,因为它破坏了程序结构,这也是我学编程语言以来老师一直说的。书本上也是如是说...
于是他们开始讨论第1,2种的优劣。 大多数孩子觉得第1种简洁,清晰
。第2种方法使函数只有一个出口。
老鸟们开始发话了: 最好的第3种!对错误处理,统一用goto err 跳转是最方便且效率最高的,从反汇编语句条数可以看出指令用的最少,消耗的寄存器也最少,效率无疑是最高的。并且,使用goto可以使程序变得更加可扩展。当程序需要在错误处理时释放资源时,统一到goto处理最方便。
高手另外提到: 几乎所有的C加密算法库,都会巨量的出现goto来处理错误 这个讨论的确使我受益匪浅!
在以往的程序中,我并没有用过goto语句,因为思想一直被教条化的教育僵硬着,没法往goto那想。 所以在很多返回错误时都是用return err;
另外,看到有些同学对直接返回与最后才返回有意见。认为直接返回的同学觉得这样对代码多的函数直观,并举出万行代码函数的例子。
读到这里我笑了...
我浏览过《重构》,《Clean Code》(代码整洁之道),对其中提出的写出让别人能看懂的代码十分有感觉。
一个上百行的代码已经是丑陋的代码了。 一个函数应该只做一件事,这是Clean Code里面的基本观点。 对有实战经验的程序员与刚出社会血气方刚的同学来说,这个问题真的能分出水平。
另外,看着这些讨论,我觉得自己看了这么多C/C++的经典书籍还是非常有用的,起码我懂得基本的“程序设计”。 适当的场景用goto可以极大的提高程序的可读性,可扩展性...
在后来看到《0 bug:C/C++商用工程之道》的时候,更是觉得Goto的用处不少。