周五查看一段代码,
发现里边有一个计算式写作:
p = 1 << (num % 8 -1);//修正见注2。
这里边num,p都是无符号字符型,
如果num是8的倍数的时候,会怎么样呢?
由于模除取余,得到的将是0 - 1,这会导致移位出错的(分析见注1)。
这段代码,将会导致当num为8的倍数时,出错。
准备修改这段代码,于是将这段代码的问题,告诉了原来实现这段代码的同事。
同事看后认为没有错,因为这段代码已经跑很长时间了。他们以前测试时没有发现错误。
当我说这里0 - 1的值是不可知的,由此引发的移位,肯定会超过一个无符号字符型的要求,会变成0.
同事认为他们测试没有错,是因为存在循环移位的问题,即高位的数移到低位上。
诚然,在汇编里确实存在循环移位,但是不记得在C中也存在这个方式。只是记得有一次看JAVA的移位,说是如果要移的位数超过变量位数会先使用要移的位数对变量位数取余,然后再移位。
后来同事又说这里的num不会是8的倍数,不会出现0 - 1的问题。
我又回去找num的出处,证明这里num确实会是8的倍数。
……
争论了半天,
结果是,同事不认为代码有问题,认为是C的隐式规则使其运行正确。
我的结论是,代码有问题,理论上通不过,因为这里最大值num只取到32,几乎只有1/10的概率才会出现这个问题,是以前测试不注意,漏掉了这个bug。
确实因为这一行代码,我们争论了半天。
现在想来,其实同事和我这样的做法在团队合作中是很低效的。这尚且是一个bug的问题。
如果当时自己在提出这个问题的时候,先将这段代码在PC上测试下,提出测试结果给同事看,可能就不会有后来的那么多争论了。也就不存在所谓的什么隐式规则了。或者在有争论的时候,我们都回去测试下,可能两分钟就结束了。
应该说自己在团队合作中的有效沟通还做的不够好。团队合作是要一起解决遇到的问题,不是争论孰对孰错。
团队合作中,有效沟通是合作的第一步。
要明确表达自己的想法,正确理解别人表达的想法。
注:
1、一开始想,可能是-1或者255,考虑到是否会因为计算过程中的隐式类型转换来取结果为255,这是不可知的。后来在Linux测试显示,这种方法算出来的是-1。因为在C语言中移位操作的右边的值不能为负,所以测试结果显示移位结果为0。这里想到一句话“代码的正确形式只有一种,错误形式却有很多种”。
2、关于这里p = 1 << (num % 8 - 1);
可以修改为:
p = 1 << ((num - 1) % 8);
考虑到单片机中的运行速度,如果优化可以改为:
p = 1 << ((num - 1) & 0x07);//当然这种方式只适合于求余的除数是2的幂情况,最好使用宏定义,使程序易读。
pentral0311_880012608 2013-4-1 13:55
1989tie_959541171 2013-3-29 20:57
用户1625273 2013-3-29 19:03
用户869009 2013-3-28 09:39
用户1394263 2013-3-27 09:53
1989tie_959541171 2013-3-27 08:16
1989tie_959541171 2013-3-27 08:15
allen_zhan_752827529 2013-3-26 16:43
用户1038389 2013-3-26 10:01
用户1009120 2013-3-26 09:41