不理解从整数到较小指针错误的转换

时间:2014-09-04 14:07:14

标签: c iar 8051

我正在使用一个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位变量。只是编译器发出警告关于一般的“整数到指针”转换?

代码工作正常,我只是想确定我不会在这里遗漏一些傻事......

4 个答案:

答案 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();必须返回一个指针。

顺便说一句,intint *都是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))