这个故事源于今天测试组测出的一个BUG,BUG被测试人员转给了我,故事便从这里开始了。

我们的系统是一个后台服务器程序,用C写的,运行在Solaris上,数据存储在数据库中,每次系统启动都要从数据库中读取配置数据。系统根据配置数据对输入的消息数据进行处理。今天的这个BUG现象就是对于一定的输入消息,系统根据配置数据的指导进行处理,结果得到的结果本应该是A,但是却得到了B。

首先咱抱着谨慎负责的态度,先从头到尾,再从尾到头检查自己的程序是否有漏洞或者疏忽大意之处,许久后,未发现问题,疑惑中,怎么经过我的程序这么一番处理,结果就是这样呢?

由于测试数据较简单,所以我对照着数据库中的数据,然后用输入消息数据在我脑子中根据程序的处理步骤人工处理了一次,终于发现了一处’不和谐的音符’。我发现数据库中一业务层配置表中的一字段的数据值有出入,赶忙打开数据库设计报告查看,一找一个准儿,问题就在这儿。

这个表中的这个字段的含义是’是否为默认项’,数据库设计报告中其值的定义是这样的:0 – 默认项;1 – 非默认项。首先我不去评论数据值设计是否合理,我们先来看看程序是如何处理的。
int is_default_item;
…..

if (is_default_item == 1) {
 /* 按照默认项处理 */
} else {
 /* 按照非默认项处理 */
}

看到这所有人都能看出问题所在了,没错,程序里想当然的以为’1′就是默认项,其他就是’非默认项’了。虽然问题找到了,但是我的心里却有了嘀咕,到底是谁错了,这个问题很显然有两个改法,一个是程序修改’1′->’0′;另一个是数据库修改,让1代表默认项。首先这里我要说我不是数据库设计的高手,可以说我自己没做过相关的数据库设计,数据库表中各字段取值设计有无经验可循我也不是很清楚。写到这可以把故事升华一下,升华成一个问题,也就是本篇的题目-0到底是’TRUE’还是’FALSE’?,这里的’TRUE’和’FALSE’并不仅仅代表真与假,而是代表更广义的含义,比如’TRUE’我们可以理解为’成功’、’正确’、’与预期目标一致’等;’FALSE’则可理解为’失败’、’错误’、’与预期目标不一致’等。

在UNIX上用C写过系统程序的人可能清楚Unix提供的API多以返回0代表调用成功,这就是一个典型的0表示’TRUE’的例子,这种返回值方式也被很多人用于程序设计中;在我们自己实现的底层库中,我们同样遵循了这样一种方式。还就我们上述的问题而言,数据库设计中’0′代表’默认项’是否就一定合理呢,相信也是见仁见智的问题;但是从程序角度,你认为:
if (is_default_item == 1) {
 /* 按照默认项处理 */
} else {
 /* 按照非默认项处理 */
}
更合逻辑还是
if (is_default_item == 0) {
 /* 按照默认项处理 */
} else {
 /* 按照非默认项处理 */
}
更合逻辑一些呢?起码我觉得第一种比较符合逻辑一些,代码可读性好些。当然如果按照下面的使用manifest constant的方式处理会比直接用literal constant更好些^_^,这样无论用0还是用1代表’默认项’起码从代码里都是逻辑通顺的,可读性好的。
#define DEFAULT_ITEM 1

if (is_default_item == DEFAULT_ITEM) {
 /* 按照默认项处理 */
} else {
 /* 按照非默认项处理 */
}

这个故事叙述到这就结束了,故事没有完,因为它在我们日常生活工作中还会时常发生,0是’TRUE’还是’FALSE’,把决定权留给大家^_^。

© 2007, bigwhite. 版权所有.

Related posts:

  1. 编译Ethereal On Windows
  2. APR源代码分析-进程篇
  3. 开始'亡羊补牢'
  4. 单元测试进行曲
  5. 当数组访问越界后