KeilC51/MDK平台 - 局部变量同级复用问题


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


1 . 前言总结

各编译器对C语言的优化导致局部变量的复用结果各有差异,以下记录局部变量的同级问题,测试平台为KeilC51

2 . 问题现象

程序设定将复数进行运算,以下运算过后test4应该real为6,imag为12,但实际运算过后test4的real为15,imag为30
在这里插入图片描述

3 . 问题原因

下图看到两个函数形参地址一样,a地址0xAE,a1地址也是0xAE,那说明局部变量被复用了,那么可以得到一个结果,一开始先把test1放入Complex_Add的a1(0xAE),然后运算Complex_Dec得出的结果再放入b1(0xB2),但是在运算Complex_Dec时,又把test2放入0xAE,那么这样造成的结果就是覆盖掉0xAE地址上原本test1传入的值,从而运算完Complex_Dec,再运算Complex_Add使,a1的缓存值已经被覆盖了,b1的值由Complex_Dec运算覆盖所以无问题,因此考虑是因为 test4 = Complex_Add(test1, Complex_Dec(test2, test3)); 这样的写法,编译器会认为test1传入和缓存与Complex_Dec的形参是同一级别,编译器把这里的传入形参局部变量地址复用
在这里插入图片描述

4 . 解决思路

为了解决以上问题,可以把Complex_Dec放在外面运算完后把结果再和Complex_Add运算,这样编译下来就无同级问题,注意无论给形参加volatile或者传入的变量定义全局都是无用的,因为这个问题在于传入变量后,编译器给局部变量编排局部地址的问题,所以为了避免这类问题,写程序时尽量防止这类传入变量与函数同级写法,除非验证过对应平台无该问题,否则应当避免这个写法


unsigned char Test_Event() {
	
	test1.real = 1;
	test1.imag = 2;

	test2.real = 10;
	test2.imag = 20;
	
	test3.real = 5;
	test3.imag = 10;

	test5 = Complex_Dec(test2, test3);
	test4 = Complex_Add(test1, test5);

	return 1;
}

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、付费专栏及课程。

余额充值