我正在使用一个16位指针宽度的8051平台。
我有一个用于处理闪存仿真的公共代码模块,并且有一个函数可以返回页面的16位起始地址:
volatile u16_t start_address = find_start_address_of_page( page );
我想将这个'地址'传递给一个想要 u8_t * 作为参数的CRC函数,所以我把它放在函数调用中,如下所示:< / p>
(u8_t *)start_address
这会生成警告
警告[Pe1053]:从整数转换为小指针
这让我感到困惑,因为 u8_t * 是16位宽,而我的变量是16位变量。只是编译器发出警告关于一般的“整数到指针”转换?
代码工作正常,我只是想确定我不会在这里遗漏一些傻事......
答案 0 :(得分:2)
您写道,您的8051平台的指针宽度为16位。
据我所知,8051有不同的地址范围 - 处理器内部RAM(最大256字节) - 外部RAM(最大64k) - 程序存储器(最大64k)
我使用的编译器(Keil)因此至少有四种不同的指针类型。 内部RAM的8位宽“数据”指针。 外部RAM的16位宽“xdata”指针。 程序存储器的16位宽“代码”指针。 一个24位宽的通用指针,可以设置为指向三种存储器类型中的任何一种。第一个字节用于选择内存类型。
警告文本可能意味着编译器希望将16位值转换为内部RAM中仅为8位宽的地址。
答案 1 :(得分:1)
如果你想使你的警告保持沉默,你可以使用一个联盟将你的信息转移到另一种类型,即
union {
u16_t origType;
u8_t *newtype;
} u;
u.origType = start_address;
假设它们的大小相同,那么您可以将u.newtype
传递给您的函数。
答案 2 :(得分:1)
由于start_address
是一个包含内存地址的变量,因此您应该声明并使用它,这意味着指针:
volatile u16_t *start_address = find_start_address_of_page( page );
当然这也意味着你的函数find_start_address_of_page();
必须返回一个指针。
顺便说一句,int
和int *
都是16位宽(在您的处理器上)这一事实是不够的。例如,由于汇编指令和/或数据总线实现的限制,大多数(所有?)16位处理器上的指针必须与偶数(2的倍数)对齐。
同样地,start_address++;
之类的内容会有所不同,具体取决于它是int
还是int *
(甚至是char *
)。如果它是int
(或char *
),则会增加1,但如果是int *
,它将增加2。
通过这个我试图表明编译器在位数之外进行了大量检查,具体取决于变量的类型(以及处理器能力)。
答案 3 :(得分:-3)
start_address的类型为u16_t,而不是指针。
如果你想将他的地址传递给CRC,那么试试这个:
((u8_t *)((u16_t *)start_address))