找回密码
 立即注册
楼主: zhangz***

遇到局部变量被意外修改的问题,发现是编译器给2个局部变量分配了相同的地址?

[复制链接]

该用户从未签到

1

主题

126

回帖

699

积分

高级会员

积分
699
发表于 2023-12-30 12:52:24 | 显示全部楼层
杨为民 发表于 2023-12-30 09:59
C251应该也有同样的问题,以后我发帖介绍OVERLAY的时候,会给大家例子的。现在吃瓜就好。新年快乐! ...

C251只要把代码优化选项里“Generate reentrant functions”选项勾上就不会有这问题,复杂程序从避免BUG方面来说C251要优于C51内核

点评

这是废话, C51 全部函数 都选 reentrant , 也不会出现这种问题, 其他方法都不好用, 哪怕像杨老师说的, 优化等级置 0 级, 在 OS 上使用, 也会出问题.  详情 回复 发表于 2023-12-30 13:36
回复 支持 反对 送花

使用道具 举报

  • TA的每日心情
    开心
    11 小时前
  • 签到天数: 169 天

    [LV.7]常住居民III

    39

    主题

    910

    回帖

    4364

    积分

    荣誉版主

    积分
    4364
    发表于 2023-12-30 13:36:27 | 显示全部楼层
    zxcv1973 发表于 2023-12-30 12:52
    C251只要把代码优化选项里“Generate reentrant functions”选项勾上就不会有这问题,复杂程序从避免BUG ...

    这是废话, C51 全部函数 都选  reentrant , 也不会出现这种问题,

    其他方法都不好用, 哪怕像杨老师说的, 优化等级置 0 级, 在 OS 上使用, 也会出问题.
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    66

    主题

    715

    回帖

    1万

    积分

    荣誉版主

    积分
    10983
    发表于 2023-12-30 13:38:16 | 显示全部楼层
    LAOXU 发表于 2023-12-30 12:31
    尊敬的杨老师, 谢谢您老 给我送的鲜花,送的玫瑰 .

    不知道是否能给您老提点建议, 这个世界上,  最好不要 ...

    那你试试让C51编译器自己主动为两个变量分配相同的地址?C51编译器不是AI编译器,所以对于C51我敢说绝对两个字。但是对于正在兴起的AI编译器和AI智能编程,我接受你的意见,肯定不会说绝对的。

    点评

    我存认自己水平有限, C51编译器 0级优化, 仅对常量优化, 不对 内存地址优化, 所以我 可能找不到 C51编译器 在 0级优化下, 主动为两个变量分配相同的地址, 但 软件都可能存在 BUG, 可能有高手会找到 , C51编译器 在某  详情 回复 发表于 2023-12-30 13:50
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    563

    主题

    9876

    回帖

    1万

    积分

    管理员

    积分
    14431
    发表于 2023-12-30 13:50:18 | 显示全部楼层
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    11 小时前
  • 签到天数: 169 天

    [LV.7]常住居民III

    39

    主题

    910

    回帖

    4364

    积分

    荣誉版主

    积分
    4364
    发表于 2023-12-30 13:50:25 | 显示全部楼层
    杨为民 发表于 2023-12-30 13:38
    那你试试让C51编译器自己主动为两个变量分配相同的地址?C51编译器不是AI编译器,所以对于C51我敢说绝对 ...

    我存认自己水平有限, C51编译器 0级优化, 仅对常量优化, 不对 内存地址优化, 所以我 可能找不到 C51编译器 在 0级优化下, 主动为两个变量分配相同的地址, 但 软件都可能存在 BUG, 可能有高手会找到 , C51编译器 在某种 特定条件下, 为两个变量分配相同的地址~~~
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    66

    主题

    715

    回帖

    1万

    积分

    荣誉版主

    积分
    10983
    发表于 2023-12-30 13:50:57 | 显示全部楼层
    本帖最后由 杨为民 于 2023-12-30 13:52 编辑

    二论  楼主10楼程序造假
    楼主在59楼说:“1楼的程序,是没问题的,当时用函数名描述,是因为我匆忙且当时根本不知道函数名和函数指针的区别,所以10楼的程序改过来,用函数指针了。10楼的程序,才是有问题的
    楼主在63楼说:“我的实际程序是类似10楼的,用了函数指针,发现调用函数和被调函数的局部变量地址相同,大惑不解。2、在1楼发帖真心请教,但当时对函数名调用和函数指针调用有什么不同,是一无所知的,以为都是一样的,而且下班前匆忙,所以描述就用函数名调用了
    因此楼主的意思发帖的次序事实是:先有编译通过的实际程序,然后发帖;先有10楼的程序(与实际程序类似,只是后发),然后由于匆忙将10楼程序修改成1楼的程序先发了;并且发1楼程序时“对函数名调用和函数指针调用有什么不同,是一无所知的,以为都是一样的”。
    那么我就基于这个事实来说明楼主的10楼造假了。
    1)楼主的10楼的代码如下:
    *g_pFunc =func2;   // 函数指针指向func2()
    func1()
    {
      xInfo * pStruc = ...;    // 局部变量,指向某结构xInfo的指针,地址 0x0236
       ...
      g_pFunc();   // 相当于调用func2()
                     // 到这里,发现 地址 0x0236 的内容被修改
      ...
    }
    func2()
    {
      uchar sw;   // 局部变量,地址居然也是 0x0236
      sw = 0;      // 这里,就会把func1的局部变量pStruc给意外修改了

    }
    我对10楼的代码的测试结果如下,测试程序文后附上:
    10楼程序.jpg
    其中为不添新程序就将“func2”函数调到了前面。
    2)然而事实是10楼的程序用KeilC51编译器编译根本通不过。首先写在函数外面的第9行就不是一个C51函数指针的定义语句格式,其次第14行“g_pFunc();”程序就根本不是C51的函数指针的调用格式。
    3)大家都知道如果一个程序被编译通过了,则表示其每行程序的语法都是正确,那么以后无论将其中几行抽出来进行编译都不会出错的,因此结论就是10楼的程序根本就是一个假的C51程序,是楼主杜撰出来的假程序。
    4)那么问题来了,对于10楼这样一个语法错误连编译都通不过的程序,楼主怎么样能够仿真运行到第15行,然后发现地址0x0236的内容被修改了呢?因此结论就是10楼所有的注释都是伪造的实验结果。
    5)更大的问题来了,楼主说10楼的程序是从起2万元的C51的实际程序中类似出来的,那么在其C51的实际程序中与10楼第14行程序对应的那一行程序一定是符合C51函数指针调用格式的,而不是像“g_pFunc();”这种有语法错误的。
    请楼主将你实际程序中的这一行程序亮出来给我们看看是什么样子的?就这一行,不需要你的全部程序,不需要下载到产品,不需要按按键,只要拿出这一行符合C51语法的就行了。
    6)我认为楼主不会亮出来,因为他知道我下面一系列问题在等着他。
    因此无需他回答,我在这里假定楼主有一行与1014行对应的真实程序,我假定那些作为注释的实验结果是存在且正确的,那么请问楼主:
    这里是STC技术交流的论坛,这里是交流正确使用C51编译器的版块,你为什么要把你正确的C51程序故意修改成10楼第14行的语法错误程序发出来欺骗网友,你为什么要把你正确的C51程序故意修改成1楼的虚假程序发出来欺骗网友,你是什么居心?你要达到什么目的?
    7)由于函数指针调用不是C51语言独有的,很多C语言编译器都支持,因此网络上有很多关于函数指针使用的程序例子和说明,用百度一查一大堆。
    我注意到楼主在1楼的表达中“发现是编译器给2个具有调用关系的...”并没有指明编译器,因此存在一种可能,楼主既没有真实的C51程序,也没有那么坏的心眼,只是从网络上搜了一段程序,而那段程序中的函数调用语句正好就是1014行的“g_pFunc();”这种形式,然后工作太累,一不小心就当做自己的创作发了出来呢?当然这是恶意揣测,不过“函数指针”的百度百科里正好有这样格式的一行程序,恰好我又看到了,我就用小人之心度了君子之腹了。
    8)当然还有另外一种可能,按照四种组合之一楼主既有真实的C51程序,也没有那么坏的心眼,只是新的一年要到了,故意拿出一行错误程序骗骗大家,和大家开个玩笑。如果这样,楼主你这个玩笑开大了,让有的网友都认为C51存在BUG

    结论:不管楼主的主观动机是什么和有没有真实程序存在,楼主的第10楼彻底是一篇欺骗网友的谎言帖子,请楼主先在这里给大家道个歉!

    论坛函数指针.rar (14.08 KB, 下载次数: 4)

    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    126

    回帖

    699

    积分

    高级会员

    积分
    699
    发表于 2023-12-30 15:11:47 | 显示全部楼层
    LAOXU 发表于 2023-12-30 13:36
    这是废话, C51 全部函数 都选  reentrant , 也不会出现这种问题,

    其他方法都不好用, 哪怕像杨老师说的,  ...

    C51没有指令集支持,都选reentrant性能损失太大,而C251都选reentrant是由指令集支持的,性能损失可忽略不计,两者天壤之别
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    1

    主题

    126

    回帖

    699

    积分

    高级会员

    积分
    699
    发表于 2023-12-30 15:17:33 | 显示全部楼层
    看前面帖子,C51如果都选reentrant的话,每个函数都要加上reentrant关键字,如果真是这样也太麻烦了,而C251只用一个选项就完事,方便程度也不一个级别
    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    66

    主题

    715

    回帖

    1万

    积分

    荣誉版主

    积分
    10983
    发表于 2023-12-30 20:57:54 | 显示全部楼层
    zhangzhonghua 发表于 2023-12-27 16:21
    大功告成,来汇报下结果。

    1、出错时的情况:Program Size: data=10.2 xdata=633 const=1084 code=13940 ...

    三论  楼主38楼实验结果造假
    1)从11楼起到37楼,楼主和网友们交流了在C51编译器中用维护函数调用树的方法 来解决由于OVERLAY产生的局部变量地址重合的问题 的方法。最后楼主在38楼宣告“大功告成”的实验结果,还将实验数据公布如下图:
    楼主结果.jpg
    其中第234行是开始实验的结果,第5行是后来补充的实验结果。
    2)首先分析第2行的实验数据。这行数据的第一列和最后一列意义明确无误:就是开始出问题的时候 由于存在OVERLAY优化产生了局部变量地址重叠现象时 的实验数据。这一行数据可以作为参考。
    3)其次分析第3行的实验数据。这行数据的第一列和最后一列意义也明确无误:就是去除了OVERLAY和不去除无用代码的结果。没有OVERLAY覆盖,自然xdata列的数字从第2行的633增加到第3行的980,这时局部变量地址重叠的现象自然就消除了。这一行数据可以作为参考。
    4)然后再来分析第4行的实验数据。这行数据的第一列和最后一列意义也明确无误:这是针对使用函数指针调用的部分进行了维护调用树操作后的结果,而且肯定是消除了局部变量地址重叠的现象后“大功告成”的结果。
    5但是第4行的实验数据是“伪造的”,它疑似是直接将第2行的实验数据复制粘贴下来,只修改了第一列和最后一列意义中文文字的结果。因此这一行的dataxdataconstcode列的数字一模一样。
    6)情况1:如果xdata的数字一样,就说明变量覆盖现象没有消除,从第11楼到第37楼的操作都是做无用功,那么“大功告成”的实验结果就是假的。
    情况2:相反如果“大功告成”,消除了局部变量地址重叠的现象,那么第4行里data/xdata列的实验结果数字之一就一定会比第2行的大,现在两行数字一模一样,必定是实验数字造假了。
    结论:无论是哪一种情况,39楼的实验结果或实验数据造假了!
    7)最后分析第5行的实验数据。这行数据的第一列和最后一列意义也明确无误:这是优化等级=0的结果。按照C51优化等级选项的定义,如果优化等级=0,则不进行OVERLAYREMOVEUNUSED操作。因此正确的第5行的实验数据应该与第3行一模一样,但是第5行的xdatacode列的数字要小,这就奇怪了!
    8)情况3:第5C51关闭了优化后,C51编译器“还自作主张地悄悄地进行了某种优化”,导致第5行的数字比正常的第3行要小。
    情况4:第3行设置了REMOVEUNUSED优化选项后,C51编译器“还自作主张地固执地多编了一些未知代码”,设置了NOOVERLAY不优化后,C51编译器“还自作主张地莫名其妙地多占用了一些RAM空间”,导致第3行的code列和xdata列的数字比正常的第5行要大。
    出现这两种情况之一都是不可思议的,因此只有一种可能:第3行和第5行中的某些数据造假了!
    9)结论:要么38楼“大功告成”的实验结论造假了,要么表中的实验数据造假了,或者两者都造假了。
    楼主:你的38帖子造假了,请你出来向大家道歉!



    回复 支持 反对 送花

    使用道具 举报

    该用户从未签到

    4

    主题

    52

    回帖

    160

    积分

    注册会员

    积分
    160
     楼主| 发表于 2023-12-30 23:34:28 | 显示全部楼层
    杨为民 发表于 2023-12-30 09:41
    (1)终于有懂行的发言了。如果要打赌,则把赌标准确地定义为:

    “对于Keil的C51编译器,只要不人为打开 ...

    优化等级=0,这个条件是霸王条款了,我必输无疑。Overlay是优化的一种手段,你都不让它跑了,还怎么赌?
    打赌的条件是,Overlay是跑着的(优化等级>=2,无NOOVERLAY指示),但没有人工干预(无OVERLAY指示)。这种情况下,如果用函数指针调用,那么调用函数和被调函数的局部变量地址可能相同。改成这个条件,你又不敢赌,哎。

    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-6-11 18:37 , Processed in 0.073292 second(s), 67 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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