Keil/MDK平台 - 变量隐式转换判断注意事项


【全文大纲】 : https://blog.youkuaiyun.com/Engineer_LU/article/details/135149485


1 . 前言总结

当在后台循环判断变量时,要留意编译器把变量送进寄存器变量中判断引发的细节问题

2 . 问题现象

在判断时,编译把变量放到内部R0-Rx寄存器变量,而MDK是32位平台,所以 R0-Rx寄存器变量 取反后为0xFFFFFF55,因此与0x00000055不相等,导致判断错误,程序逻辑异常

u8 i = 0x55;
u8 j = 0xaa;
if (i == ~j) {
	return 1;
}
return 0;

3 . 解决思路

为了解决以上问题,可在取反前缀加强转转换告诉编译器这里无论平台多少位,后续转成汇编都要以8位范围来判断

u8 i = 0x55;
u8 j = 0xaa;
if (i == (u8)~j) {
	return 1;
}
return 0;

4 . 细节扩展

除了上述情况,还有各种操作符使变量隐式转换,例如下述判断方式,结果return 0; 原因是j的结果左移后为0x00000000,因为编译有优化,这些判断都基于缓存来判断实现,u8 << 16,如果是Keil平台则超出了默认的16位范围,因此超出范围,所以为0x00000000,处理方法也是制转换j为u32, (u32)j<<16 ,这样编译下来,j就为32bit变量,编译器判断比较时就按u32来判断了

u8 i = 0x550000;
u8 j = 0x55;
if (i == (j<<16)) {
	return 1;
}
return 0;

5 . 总结

优秀的代码,在任何优化下,基本很少影响正常运行 (不排除极端优化导致的逻辑问题),一般考虑定义时的类型,不能完全相信编译器定义变量时的类型,嵌入式要考虑底层硬件平台的优化转换导致的类型差异,因此我们要想保证一段代码是我们想要的逻辑,就告诉编译器这里要做成怎样的逻辑,不可自行干预影响。

技术交流群 : 745662457
群内专注 - 问题答疑,技术研究

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极客 - L U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值