原创 调试中的团队合作反思

2013-3-24 15:59 2598 13 28 分类: 消费电子

周五查看一段代码,

发现里边有一个计算式写作:
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的幂情况,最好使用宏定义,使程序易读。

文章评论15条评论)

登录后参与讨论

pentral0311_880012608 2013-4-1 13:55

深有体会,还有类型不匹配的,曾经有人报告编译器出错了,吓了我一大跳,这么高深的DEBUG被他发现了,过去看了一下代码,也就是跟LZ的代码风格差不多,优先级没弄明白,一行代码出现N多的运算符,不错才怪,后然我强制规定他们一个运算一行,if后面一定要加{}==

1989tie_959541171 2013-3-29 20:57

我自己有时候都有这个状态,还是有些地方没有做到。我想,这里我们或许看到问题后,给自己和他人留些时间,多一份分析与思考,多一份沟通与理解。

用户1625273 2013-3-29 19:03

搞技术的人,一般都比较自信,不愿意承认自己的问题。一旦发现自己错了,基本上都是不吭声。

用户869009 2013-3-28 09:39

给朵鲜花了。 呵呵 www.igbtic.com

用户1394263 2013-3-27 09:53

深有感触,遇到这样的自信的同事很头疼……

1989tie_959541171 2013-3-27 08:16

在《代码大全》上看到,程序是写给人看的,之后才是机器运行。控制复杂度,是软件的趋势。

1989tie_959541171 2013-3-27 08:15

你在里边提到的结果,有些像0xFF向左移动了1位,不知道我理解的对吗?对于<<操作符,被移位的数在<<左边,要移位的个数在<<的右边,1 << 0xFF,指1向左移位255次。C语言约定,<<右边要移位的个数不能为负。在Linux测试中,发现即使num为无符号整形,0 - 1得到的结果,都是-1.

allen_zhan_752827529 2013-3-26 16:43

不同的编译器, 可能得到的结果不同. 如果我们假设操作的是 32-bit MCU, 如你假设, num 为 8 之倍数, 那么结果是 1<< 0xFFFF. 我印象里面, 左移分为两种, 一种是有符号左移, 一种是无符号左移. 无论是哪种左移, 结果应为 0xfffe? 我的算法有错误吗? p 被定义为 unsigned char, 这意味着 0xfffe 被强制转换为 0xfe? 可在编译器中, 设定 num=8 进行简单验证下.

用户1038389 2013-3-26 10:01

实际上,程序写简单点,不要那么多高深的语法,程序员要想着自己是设计师,而不是艺术家。 笔者说的没错,现在很多技术人,出了问题后,往往第一时间都是为自己辩解,而不是想办法解决问题。

用户1009120 2013-3-26 09:41

你们的头在干什么?
相关推荐阅读
catch2000 2015-07-19 11:44
信号线小电阻的作用
在一块新的PCB上,测试系统能否正常运行的时候,发现系统上电后没有正常启动。  系统框图如下:   在上电的时刻,CPU A(GPIO电平2.6V)会向串口发送启动日志数据,CPU A启动后,...
catch2000 2015-07-05 17:04
协议设计中ACK机制的影响
在TCP/IP中,延时ACK和Nagle算法。  TCP为了同时处理成块数据(通常为512字节的用户数据)和交互数据(通常用户数据比较少,例如不大于10个字节),采用了延时ACK和Nagle算法...
catch2000 2015-05-23 15:48
话说物联网操作系统
最近好多家都宣布推出自己的物联网操作系统。   1. Google将要在Google I/O大会发布的Brillo; 2. 三星推出的Artik芯片搭载Mentor Graphics的...
catch2000 2015-03-31 23:52
不要采用异或来交换两个变量
在进行两个变量的时候,经常会看到有些书误人子弟的推荐使用异或的方式: 方式一 {   x = x ^ y;   y = x ^ y;   x = x ^ y; } 而不是...
catch2000 2014-10-09 07:28
为什么要测试先行
在产品的研发过程中,测试一项至关重要。不论是软件还是硬件。   软件的测试先行,在研发过程中,就做到质量的保证,因为在出现Bug的时候,容易定位Bug,而且即使是在客户端出现Bug,也能够...
catch2000 2014-10-09 07:26
C语言的面向对象编程(一)
一、前言 对于编程而言,重要的是解决问题的方式,而不是语言本身。面向对象与面向过程是解决问题和思考问题的方式。C语言常说是面向过程开发的语言,因为其缺少很多对于面向对象特性的支持。但,这并不影...
我要评论
15
13
关闭 站长推荐上一条 /2 下一条