调试中的团队合作反思

周五查看一段代码,

发现里边有一个计算式写作:
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的幂情况,最好使用宏定义,使程序易读。
 
网友1:直接拿出会产生bug的测试用例和结果摔dev脸上不就得了。。。
 
网友2:無言 最後 這些代碼 寫出來的 安全性 無法 保證 錯誤 還是必然發生 甚至 說句不好聽的 出問題的時候 根本 無法 猜想 追蹤 到 這段 代碼 程序 雖說 有時候 要考慮 簡化 但是 如果 考量到 在不同平台 上使用 則必須 絕對化 不能有 使用 編譯器特性 系統特性 等。
网友5回复:深有体会,还有类型不匹配的,曾经有人报告编译器出错了,吓了我一大跳,这么高深的DEBUG被他发现了,过去看了一下代码,也就是跟LZ的代码风格差不多,优先级没弄明白,一行代码出现N多的运算符,不错才怪,后然我强制规定他们一个运算一行,if后面一定要加{}==
 
网友3:不同的编译器, 可能得到的结果不同. 如果我们假设操作的是 32-bit MCU, 如你假设, num 为 8 之倍数, 那么结果是 1<< 0xFFFF. 我印象里面, 左移分为两种, 一种是有符号左移, 一种是无符号左移. 无论是哪种左移, 结果应为 0xfffe? 我的算法有错误吗? p 被定义为 unsigned char, 这意味着 0xfffe 被强制转换为 0xfe? 可在编译器中, 设定 num=8 进行简单验证下.
作者回复:你在里边提到的结果,有些像0xFF向左移动了1位,不知道我理解的对吗?对于<<操作符,被移位的数在<<左边,要移位的个数在<<的右边,1 << 0xFF,指1向左移位255次。C语言约定,<<右边要移位的个数不能为负。在Linux测试中,发现即使num为无符号整形,0 - 1得到的结果,都是-1.
 
网友4:实际上,程序写简单点,不要那么多高深的语法,程序员要想着自己是设计师,而不是艺术家。 笔者说的没错,现在很多技术人,出了问题后,往往第一时间都是为自己辩解,而不是想办法解决问题。
作者回复:在《代码大全》上看到,程序是写给人看的,之后才是机器运行。控制复杂度,是软件的趋势。
 
永不止步步 发表于09-30 16:16 浏览65535次
分享到:

已有0条评论

暂时还没有回复哟,快来抢沙发吧

添加一条新评论

只有登录用户才能评论,请先登录注册哦!

话题作者

永不止步步
金币:67410个|学分:308117个
立即注册
畅学电子网,带你进入电子开发学习世界
专业电子工程技术学习交流社区,加入畅学一起充电加油吧!

x

畅学电子网订阅号