硬汉嵌入式论坛

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

[编程语言] 记一次开发踩坑,一个玄学的现象

[复制链接]

0

主题

4

回帖

4

积分

新手上路

积分
4
发表于 2024-1-12 10:59:46 | 显示全部楼层 |阅读模式
本帖最后由 longger 于 2024-1-12 11:01 编辑

记一次开发踩坑
事情的起因是,我们从一家芯片厂家获取了一套代码,这套代码是厂商为推广他们的芯片提供的。这套代码要应用到我们的产品中还需要大量的修改,在我理清了这套代码逻辑后开始了修改之路。经过一顿操作,消灭了各种错误警告之后也算基本完成了。不出意外意外还是发生了,有问题!

然后到了各种排查调试的阶段,像这种编译器查不到的问题最难搞定,尤其是这套代码还是很复杂的。我排查了每一处修改,在我看来都没问题,翻来覆去查了两天。我觉得可能是某个运算逻辑被我改乱了,但是死活找不到在哪。经过苦苦挣扎我选择重新再来一次。

然后有一个函数引起了我的注意。
int32_t hall_rotor_location_interpolation(int32_t);
                函数的声明↑
int32_t hall_rotor_location_interpolation(int32_t phase_pre)
{
    float phase_diff = 0;
    uint16_t phase_diff_set = 10;
    int32_t phase_temp;
  
    phase_diff = (float)NUMBER_OF_PAIRS * hall.speed * 360 / (60 * frequency_now) * 100;
    if ((MC_STATE_RUNNING == state) && (hall.speed < 500))
    {
       phase_diff = phase_diff_set;
    }
    if (DIRECTION_CW == direction)
    {
       phase_temp -= (phase_diff);
    }
    else
    {
       phase_temp += (phase_diff);
    }
    if (phase_temp > 36000)
    {
       phase_temp -= 36000;
    }
    else if (phase_temp < 0)
    {
       phase_temp += 36000;
    }
    return (phase_temp);
}
      函数的定义↑
在第一修改时我发现这个函数的形参 phase_pre 并没有被使用,于是选删除了。
当我又一次看这个函数时发现了不对,这个函数没有使用 传入参数, 而是主要在使用局部变量 int32_t phase_temp; 这个变量并没有被赋予初始值,然而在后续的逻辑代码中却直接使用了这个变量,从逻辑代码中不难看出这肯定是存在问题的,因为phase_temp的值是不确定的。于是我想 这个局部变量初始值应该是传入参数的值,即int32_t phase_temp = phase_pre 于是我做了这样的修改问题也就解决了。

但是这个函数我却看不懂了,为什么局部变量初始值会等于形参的值呢?从代码上看二者没有任何联系。
hall.phase = hall_rotor_location_interpolation(hall.phase);
        这是函数的调用↑
1.png
                   keil调试结果
我们从keil的调试结果里可以看到他们的值确实是相同的。
在这里向大佬请教一下这是什么原理。我尝试模仿但都不存在这个现象。
观察这个函数,可以看出应该这样写 int32_t phase_temp = phase_pre; 或者直接使用phase_pre  。如果说原理上作者这样的写法是可以的,那就很难不让人认为这是作者故意在挖坑。故意复杂化代码,让使用者掉尽头发,这种行为实属可恶。
如果C语言语法上不允许这样做,作者也无意这样做,只是忘了让phase_temp = phase_pre 。程序又巧合的能运行起来,这确实很搞人心态,程序开始玄学了起来。

回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2024-1-12 11:03:04 | 显示全部楼层
如果这个是语言特性,有没有大佬来解答一下。谢谢!
回复

使用道具 举报

3

主题

120

回帖

129

积分

初级会员

积分
129
发表于 2024-1-12 11:52:19 | 显示全部楼层
本帖最后由 skyshine 于 2024-1-12 15:05 编辑

源码里这个地方是 int32_t phase_temp = phase_pre;
2021-08-16, V1.3.0, FOC demo
回复

使用道具 举报

0

主题

124

回帖

124

积分

初级会员

积分
124
发表于 2024-1-12 12:29:48 | 显示全部楼层
现在的编译器对代码优化的程度很高, 很多时候编译后就跟你原代码的处理先后不一样, 特别是针对局部变量, 所以企图用Watch查看局部变量在过程中的值很多时候就不符合源代码的运行逻辑。
简单而言就是编译器只针对你代码的结果, 过程并不一定会按你代码的方式运算。

解决方式, 把局部变量暂时搬到函数外,并加上volatile(就是暂时让它成了全局的),用watch也能实时查看变量,这时候编就会百分百的按你的编程逻辑跑了。
回复

使用道具 举报

3

主题

120

回帖

129

积分

初级会员

积分
129
发表于 2024-1-12 13:54:42 | 显示全部楼层
按楼主的描述来看,调试里结果是正常的,但是没法复现,实际运行结果也是有问题的,大概率是巧合,变量初始值正好是其他函数用到的相同局部变量值。
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2024-1-12 13:59:51 | 显示全部楼层
skyshine 发表于 2024-1-12 11:52
github搜了下,看到别人上传的源码了,源码里这个地方是 int32_t phase_temp = phase_pre;
你这份代码可能 ...

啊,我手上这份是签了保密协议的,没想到GitHub能搜到,这份是 8-16 V1.3.0.邪门了
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2024-1-12 14:00:34 | 显示全部楼层
Edmund1964 发表于 2024-1-12 12:29
现在的编译器对代码优化的程度很高, 很多时候编译后就跟你原代码的处理先后不一样, 特别是针对局部变量, ...

编译器优化关了
回复

使用道具 举报

0

主题

4

回帖

4

积分

新手上路

积分
4
 楼主| 发表于 2024-1-12 14:02:28 | 显示全部楼层
skyshine 发表于 2024-1-12 11:52
github搜了下,看到别人上传的源码了,源码里这个地方是 int32_t phase_temp = phase_pre;
你这份代码可能 ...

老哥用啥关键词搜的
回复

使用道具 举报

3

主题

120

回帖

129

积分

初级会员

积分
129
发表于 2024-1-12 14:20:20 | 显示全部楼层
[C] 纯文本查看 复制代码
#include <stdio.h>
int test1(int test)
{
	int b=321;
	return b;
}
int test2(int test)
{
	int c;
	return c;
}

int main()
{
	test1(789);
	int a=345;
	a=test2(123);
	printf("%d",a);
        return 0;
}


这里test2打印出来的结果就是test1函数里局部变量的值。如果把test1函数和test2函数调换位置,打印的值又不同了。正常情况下局部变量初始化都要赋值,不然大概率就是之前某个函数的局部变量的值。
回复

使用道具 举报

3

主题

120

回帖

129

积分

初级会员

积分
129
发表于 2024-1-12 14:51:03 | 显示全部楼层
longger 发表于 2024-1-12 14:02
老哥用啥关键词搜的

别搜了,估计是忘了设置成私人仓库泄露出来的
回复

使用道具 举报

3

主题

120

回帖

129

积分

初级会员

积分
129
发表于 2024-1-12 15:13:50 | 显示全部楼层
站长能把github相关的讨论编辑一下吗,怕引起不必要的麻烦
回复

使用道具 举报

4

主题

160

回帖

172

积分

初级会员

积分
172
发表于 2024-1-12 15:33:20 | 显示全部楼层
形参就是个临时变量,你用个临时变量给他,编译器就直接省略了你定义的临时变量。没必要搞两个。一样也很正常
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-4-29 04:22 , Processed in 0.197557 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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