庄永 发表于 2023-12-29 14:41:15

设计质量最好程序员自己保证代码没有隐藏BUG

今天在看公司一份很老的代码的时候,发现一个问题代码,如下

double a = -50;
uint32_t b = (uint32_t)(a*10);
就是这简单的一句话,很容易爆雷。在使用和不使用微库的时候执行结果完全不一样。但是又没有改到这块代码,所以测试也没测,结果导致上线后有BUG。
本来这种强制转换是不应该出现的,但是由于当时没有使用微库,执行的结果刚好在允许范围内,通过了所有测试用例。
后面迭代的时候不小心使用到的微库,结果结果完全不一样,但是由于迭代开发人员更换,没人会注意也不会特意去看这些看上去容易出错的代码,测试也不会可以去测。所以问题就出来了
这种问题,后期很难自主发现。最好的是设计之初考量好

eric2013 发表于 2023-12-29 14:59:55

微库对这个代码有影响?这个是示例代码,不是你们的原始代码吧,一会我也试试。

emwin 发表于 2023-12-29 18:31:09

请教怎么达到“代码没有Bug”的境界

庄永 发表于 2023-12-29 21:13:22

eric2013 发表于 2023-12-29 14:59
微库对这个代码有影响?这个是示例代码,不是你们的原始代码吧,一会我也试试。

原始代码逻辑,不加微库b=0,加了b=500

庄永 发表于 2023-12-29 21:14:49

emwin 发表于 2023-12-29 18:31
请教怎么达到“代码没有Bug”的境界

很难达到,但是语法BUG还是尽量不要有。藏的深而且不好发现,就是一个定时炸弹

庄永 发表于 2023-12-29 21:31:21

eric2013 发表于 2023-12-29 14:59
微库对这个代码有影响?这个是示例代码,不是你们的原始代码吧,一会我也试试。

刚又在另外版本MDK试了试,还是一样的结果,而且结果都不是能够想到的值

Edmund1964 发表于 2023-12-29 21:42:05

我不太信微库有这影响, 估计是被优化后不能直接查看局部变量吧,把这变量搬到函数外测试一下, 可能根本就没问题。

庄永 发表于 2023-12-29 23:43:11

Edmund1964 发表于 2023-12-29 21:42
我不太信微库有这影响, 估计是被优化后不能直接查看局部变量吧,把这变量搬到函数外测试一下, 可能根本就 ...

没有开优化

Edmund1964 发表于 2023-12-30 02:44:24

庄永 发表于 2023-12-29 23:43
没有开优化

AC6的优化不需要打开的, 你就把这局部变量暂时搬出函数外成全局的, 测试一下就知道答案了

nnqtdf 发表于 2023-12-30 07:31:08

庄永 发表于 2023-12-29 21:13
原始代码逻辑,不加微库b=0,加了b=500






还真是这样

wh201906 发表于 2023-12-30 11:13:48

根据C11的标准来看,(-1,Utype_MAX+1)范围以外的浮点数转为无符号整数是未定义行为,因此出现什么结果都有可能,取决于具体实现
https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
(见6.3.1.4)

庄永 发表于 2023-12-30 12:39:02

wh201906 发表于 2023-12-30 11:13
根据C11的标准来看,(-1,Utype_MAX+1)范围以外的浮点数转为无符号整数是未定义行为,因此出现什么结果都 ...

是的,其实这就是设计人员没有注意编码导致的,设计之初严格按照一些规范来就不会出这些问题,C语言看着很少东西,但是真的要全部掌握很难

apleilx 发表于 2023-12-31 08:50:15

不要在声明时赋值或者运算试试,赋值和运算单启一行。

tcs_stm32 发表于 2023-12-31 15:42:06

原因是不是这样, -50的二进制码格式是 1 10000000100 1001000000000000000000000000000000000000000000000000, 小端模式下, 仅获取了低32位的数值。


红烧鱼头 发表于 2023-12-31 18:05:26

apleilx 发表于 2023-12-31 08:50
不要在声明时赋值或者运算试试,赋值和运算单启一行。

这其中的原理是什么呢?

JIAYU 发表于 2024-1-2 11:43:28

uint32_t 改为 int32_t 试试呢?

Hzzz 发表于 2024-1-2 15:34:14

double 强转uint32 ,double是个8字节的,uint32是个4字节的,这样转肯定是会存在未知问题的吧

2859932063 发表于 2024-1-2 18:01:03

double a = -50;
int32_t b = (int32_t)round(a * 10);

鱼小木 发表于 2024-1-2 19:54:01

前两天也遇见过这个问题,(VCVT.U32.F32)这个是将单精度float转化为uint32时的汇编指令。对于负数,这条指令的转换结果都是0。如果float转化为int32,则一且正常。

庄永 发表于 2024-1-2 23:55:40

2859932063 发表于 2024-1-2 18:01
double a = -50;
int32_t b = (int32_t)round(a * 10);

一样有问题的。这个讨论的本质是不要出现11楼那个坛友说的那种问题。即使换成int32_t,double转过去也一样有这个隐患存在
页: [1]
查看完整版本: 设计质量最好程序员自己保证代码没有隐藏BUG