本帖最后由 fantasyhpu 于 2024-5-30 14:16 编辑
很多人使用keil时遇见过这个恶心bug: Encountered an improper argument
其实它还有另外一个恶心bug: keil c51的局部变量名能影响编译结果。这个恶心bug是我最近遇见的,不知道坛友遇见过没有。
复现代码非常简单,普通的C51代码:
[C] 纯文本查看 复制代码 #include "reg52.h"
#include "stdio.h"
#include "intrins.h"
void uart_init()
{
SCON = 0x52;
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
}
void main()
{
unsigned int a=17; // 注意局部变量a的名字造成了该bug
unsigned int b;
uart_init();
for(b=2;b<=a-1;b++)
{
if(a%b==0)
break;
}
if(b<a)
printf("%d is not a prime number",a);
else
printf("%d is a prime number",a);
while(1);
}
具体过程是:
1. 解压附件test2.zip,然后使用main.c中的代码,新建一个C51工程,注意main()函数中第一行的局部变量名字“a”,正是这个名字造成了该bug。
2. 编译新建的C51工程,然后可以软件仿真一下,一切正常,这表明第一次编译后生成的.hex文件正常。(也可以不软件仿真,直接将.hex文件下载到单片机中,第一次编译的.hex文件正常运行)
3. 退出仿真界面,重复编译一下后,生成的.hex文件就不正常了,可以软件仿真看看,观察局部变量a和b的值,单步运行表明它俩在乱跳。这表明第二次编译该工程后,生成的.hex文件就不正常了。(也可以不软件仿真,直接将.hex文件下载到单片机中,后续编译的.hex文件不能正常运行)
4. 若将main()函数中的局部变量a和b挪到函数外面成为全局变量,则无论编译多少次,生成的.hex文件都是正常的。
不想新建工程的坛友可以观察下面的gif动画,注意在第二次编译后,局部变量a和b的值就不正常了。(用的是从官网下的最新的keil c51v961版本)
|