【编程好习惯】判断函数的返回值

来源:互联网 发布:天虹商场怎么样知乎 编辑:程序博客网 时间:2024/06/02 05:11

本文出自 “至简李云” 博客,请务必保留此出处http://yunli.blog.51cto.com/831344/258925

调用一个函数后要检查函数的返回值,以决定程序是继续应用逻辑处理还是出错处理,这理应是一个常识,但在现实中,却存在大量不检查函数返回值的代码。既然是常识,但却得不到重视,这不能简单地说程序员不知道其危害性。相信读者也明白不检查函数的返回值其危害是什么,因此,也不打算举例说明其所带来的问题,而是试图去探究程序员为什么不按这一常识去做。

要判断函数的返回值,不可避免地要面对一个问题 —— 出错了怎么办?这显然不是一个简单的问题,在这问题的背后可能是在问:在项目中一个错误如何表达?项目是否定义了出错处理的准则或机制?

如果一个项目没有一种有效的方法表达一个错误,那么就会出现对于出错处理的混乱状况。当出现错误时,仅仅通过C库中已经定义了的那么几个错误码并不能有效地表达应用错误。之所以需要有效地表达各类错误,是因为针对不同的错误可能需要采用完全不同的出错处理方法。不同的错误可能收敛于几个错误类别,但还是存在一定程序的发散性。没有有效的方法去定义一个错误,势必会造成程序员在面对函数返回错误时需要进行大量的思考,其所带来的个人思考成本还是很高的,进而程序员干脆就不去考虑它。在《错误管理》一文中介绍了一种通过定义错误码表达错误的方法,项目中这种类似方法的存在,能大大地降低程序员个体在面对函数返回错误时的思考成本。从程序员的角度来说,如果项目没有一种明确的错误表达方式,且即使按其个人的想法进行错误处理也最终会进入一种混乱状态,也就是说考虑与否可能结局都是一样的,只是从一种混乱形式变成了另一种,这应当是程序干脆不进行出错处理的一个重要原因。

一个项目光定义好了一种通用的方法去表达一个错误就好了吗?为了进一步说明问题,需要借助一定的项目实际来帮助继续分析。假设一个电信产品是进行电话呼叫处理的,在这个产品中的呼叫处理模块对于每一个用户电话连接的建立,都需要从DSP处理器上获取一个DSP通道(读者可以想到会有一个DSP通道管理模块存在于系统中)以对电话语音数据进行编解码工作,那么当DSP通道被用尽了以后呼叫处理模块该怎么办?显然,这里DSP通道用尽就是一种错误,如果这个错误被定义成了一个错误码ERROR_CP_NOCHANNEL,那进一步的问题是,这一错误出现时,呼叫出理模块应当采取怎样的处理呢?可能的做法有:
1) 由于系统有一定的用户容量限制,DSP通道的用尽意味着用户数量超过了系统所能处理的最大用户数,因此,这种情形下即使出现了ERROR_CP_NOCHANNEL错误,也只需记录一个错误日志,并结束对这一用户的后续呼叫处理逻辑。或许,ERROR_CP_NOCHANNEL的出现严格地说不是错误。
2) 虽然系统有最大用户数的限制,但通过程序中的统计变量可以确定,当前的用户数根本没有超过最大用户数。因此,ERROR_CP_NOCHANNEL错误的出现意味着系统有严重的资源泄漏,从而造成DSP通道不足,这次是真正的错误了。如果是这样又有两种出错处理方法。其一是直接对产品进行复位,如此一来,就解决了资源的泄漏问题,但其缺点也是明显的,即在复位时,本来正在通话的用户将会出现掉话的问题。其二,只是记录一个错误日志,然后终止对这一用户的后续处理,也不进行产品复位操作以保证当前正接通的用户能继续进行通话,系统的资源泄漏也不管,直到系统资源泄漏到不能提供任何一个服务为止再复位。

从ERROR_CP_NOCHANNEL错误的可能处理来看,不是仅有错误码的定义就完事了,而是需要从应用的层面定义好每种(不一定是每个)错误出现时的处理逻辑是什么。这里所例举的呼叫处理错误,其实在一个产品中的任一个模块都可能存在相类似的问题,只是形式变了。而面对一个错误,其具体的应对方法往往需要考虑很多因素,有时面对的有可能是两难问题。如果一个项目没有定义好各类错误的大致处理思路,而是完全由程序员自己去思考,那还是会导致程序员的个体思考成本过高这一问题,而且没有统一出错处理思路的指导,不同程序员所做出来的出错处理方法有可能就会是相悖的,其结果就是另一种混乱局面出现了!另外,即使定义了项目的出错处理思路,那这些出错逻辑是放在哪里处理呢?是将其分散在程序的各模块呢?还是集中处理?如果是分散处理则有可能出现大量的冗余代码,且可能存在一定的困难。因为有些错误的处理,需要得到很多其它的信息,如果分散在程序的各处,那么意味着这些信息需要很大程度的公开,这会造成程序的结构出现一定的退化。笔者的观点是,究竟采用分散还是集中处理方式并没有绝对,但应当以集中出错处理为主。在后面笔者将会写一篇文章志门阐述出错处理方法,到时读者可以看到更为深入的一些内容。


至此,程序员不按常识进行函数返回值的判断的深层次原因分析过了,那要解决这一问题显然不能通过将“判断函数返回值”这几个字通过使用初号字体打印出来并贴在程序员的办公桌显眼处这一方式加以解决。出错处理其实不是程序员的个人私事,而是项目的集体事。要根本解决它,应当从项目全局的角度去着手。以下几点项目组可以考虑去做:
1) 从项目的层面定义好一个错误的表达方式是什么。通常,在C程序中需要定义错误码,而在C++中需要定义异常,当然在错误管理》一文中也介绍了可以通过将两者结合起来做以简化错误表达。
2) 从项目的层面定义好各大类错误的处理思路和方法。另外,在项目团队中还要打造一种探讨出错处理思路和方法的氛围,这样更容易在团队中集思广义形成共识,从而为这些方法的实施铺平道路。
3) 在设计层面提供一定的错误处理机制以帮助减少程序出错时的代码工作量,这能有效的促进程序员积极面对函数的错误返回值。

无论如何,要形成一种勇于面对函数出错和积极思考出错处理方法的文化对于项目团队来说不是一件容易事,但却非常重要。另外,有这方面的意识比没有要好,重视比不重视要好,当然做比不做又要更好。


0 0
原创粉丝点击