硬汉嵌入式论坛

 找回密码
 立即注册
查看: 893|回复: 19
收起左侧

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

  [复制链接]

75

主题

684

回帖

909

积分

金牌会员

积分
909
发表于 2023-12-29 14:41:15 | 显示全部楼层 |阅读模式
今天在看公司一份很老的代码的时候,发现一个问题代码,如下

[C] 纯文本查看 复制代码
double a = -50;
uint32_t b = (uint32_t)(a*10);

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

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106746
QQ
发表于 2023-12-29 14:59:55 | 显示全部楼层
微库对这个代码有影响?这个是示例代码,不是你们的原始代码吧,一会我也试试。
回复

使用道具 举报

210

主题

1043

回帖

1683

积分

至尊会员

More we do, more we can do.

积分
1683
发表于 2023-12-29 18:31:09 | 显示全部楼层
请教怎么达到“代码没有Bug”的境界
回复

使用道具 举报

75

主题

684

回帖

909

积分

金牌会员

积分
909
 楼主| 发表于 2023-12-29 21:13:22 | 显示全部楼层
eric2013 发表于 2023-12-29 14:59
微库对这个代码有影响?这个是示例代码,不是你们的原始代码吧,一会我也试试。

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

使用道具 举报

75

主题

684

回帖

909

积分

金牌会员

积分
909
 楼主| 发表于 2023-12-29 21:14:49 | 显示全部楼层
emwin 发表于 2023-12-29 18:31
请教怎么达到“代码没有Bug”的境界

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

使用道具 举报

75

主题

684

回帖

909

积分

金牌会员

积分
909
 楼主| 发表于 2023-12-29 21:31:21 | 显示全部楼层
eric2013 发表于 2023-12-29 14:59
微库对这个代码有影响?这个是示例代码,不是你们的原始代码吧,一会我也试试。

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

开了微库

开了微库

没开微库

没开微库
回复

使用道具 举报

0

主题

124

回帖

124

积分

初级会员

积分
124
发表于 2023-12-29 21:42:05 | 显示全部楼层
我不太信微库有这影响, 估计是被优化后不能直接查看局部变量吧,把这变量搬到函数外测试一下, 可能根本就没问题。
回复

使用道具 举报

75

主题

684

回帖

909

积分

金牌会员

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

没有开优化
回复

使用道具 举报

0

主题

124

回帖

124

积分

初级会员

积分
124
发表于 2023-12-30 02:44:24 | 显示全部楼层

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

使用道具 举报

1

主题

92

回帖

100

积分

初级会员

积分
100
发表于 2023-12-30 07:31:08 | 显示全部楼层
庄永 发表于 2023-12-29 21:13
原始代码逻辑,不加微库b=0,加了b=500

QQ截图20231230072858.png
QQ截图20231230072953.png



还真是这样

回复

使用道具 举报

1

主题

72

回帖

75

积分

初级会员

积分
75
发表于 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)
回复

使用道具 举报

75

主题

684

回帖

909

积分

金牌会员

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

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

使用道具 举报

14

主题

62

回帖

104

积分

初级会员

积分
104
发表于 2023-12-31 08:50:15 | 显示全部楼层
不要在声明时赋值或者运算试试,赋值和运算单启一行。
回复

使用道具 举报

8

主题

135

回帖

159

积分

初级会员

积分
159
发表于 2023-12-31 15:42:06 | 显示全部楼层
原因是不是这样, -50的二进制码格式是 1 10000000100 1001000000000000000000000000000000000000000000000000, 小端模式下, 仅获取了低32位的数值。

screenshot20231231.png
回复

使用道具 举报

5

主题

31

回帖

46

积分

新手上路

积分
46
发表于 2023-12-31 18:05:26 | 显示全部楼层
apleilx 发表于 2023-12-31 08:50
不要在声明时赋值或者运算试试,赋值和运算单启一行。

这其中的原理是什么呢?
回复

使用道具 举报

1

主题

66

回帖

69

积分

初级会员

积分
69
发表于 2024-1-2 11:43:28 | 显示全部楼层
uint32_t 改为 int32_t 试试呢?
回复

使用道具 举报

13

主题

52

回帖

91

积分

初级会员

积分
91
发表于 2024-1-2 15:34:14 | 显示全部楼层
double 强转uint32 ,double是个8字节的,uint32是个4字节的,这样转肯定是会存在未知问题的吧
回复

使用道具 举报

3

主题

96

回帖

105

积分

初级会员

积分
105
发表于 2024-1-2 18:01:03 | 显示全部楼层
double a = -50;
int32_t b = (int32_t)round(a * 10);
回复

使用道具 举报

1

主题

12

回帖

15

积分

新手上路

积分
15
发表于 2024-1-2 19:54:01 | 显示全部楼层
前两天也遇见过这个问题,(VCVT.U32.F32)这个是将单精度float转化为uint32时的汇编指令。对于负数,这条指令的转换结果都是0。如果float转化为int32,则一且正常。
回复

使用道具 举报

75

主题

684

回帖

909

积分

金牌会员

积分
909
 楼主| 发表于 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转过去也一样有这个隐患存在
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-3 21:40 , Processed in 0.229190 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表