为什么显示 "Invalid type conversion"?
Why is this showing "Invalid type conversion"?
我有这段C代码(对于MSP430平台,cl430
编译器):
void function(uint8_t * x){
// This variable is defined in the linker file as "X_ADDR = 0xE000;"
extern uint32_t X_ADDR;
uint16_t i = 0;
uint16_t size = 10;
uint32_t dst_addr = (uint32_t) &X_ADDR;
for (i=0; i < size; i++){
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
}
我的理解是这样的,但我猜这里是我错的地方:
*((uint8_t *) (dst_addr+i)) = *(x + i);
| | | |
V V V V
*((uint8_t *) (u32 + u16)) = *(u8*+u16);
*((uint8_t *) (u32)) = *(u8*);
*(u8*) = u8;
u8 = u8;
该平台是 16 位的,但它支持 20 位的扩展寻址模式。
对此有什么提示吗?应该怎么做呢?提前致谢
它反对整数dst_addr
到指针的转换,而不是uint8_t
的赋值
$ gcc -c -Wall -W type.c
type.c: In function 'function':
type.c:11:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
^
和 clang 提供类似的:
$ clang -c type.c -W -Wall
type.c:11:12: warning: cast to 'uint8_t *' (aka 'unsigned char *') from smaller integer type 'unsigned int'
[-Wint-to-pointer-cast]
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
^
(clang 3.4.2; gcc 4.8.5)
从 int 转换为指针总是令人怀疑,而且我不确定是否有办法告诉编译器你是认真的,至少如果你打开所有警告(这是一个很好的做法) ).
您似乎在使用 64 位指针的 64 位编译器上得到了这个。将 32 位整数转换为 64 位指针是有问题且不可移植的。
使用专用于此目的的可移植整数类型来更正此问题:
uintptr_t dst_addr = 0x00FFABCD;
现在它可以在所有主流 64 位编译器上干净地编译。在 gcc 上试过,clang icc -std=c11 -Wextra -Wall -pedantic-errors
,没问题。
此外,访问绝对地址时,几乎肯定需要volatile
限定指针。
您正在将 32 位整数转换为 16 位指针。
为确保您的整数类型与指针大小相同,请使用 <stdint.h>
中的 uintptr_t
。
并且当您将 X_ADDR
视为字节数组时,最好这样声明它:
extern uint8_t X_ADDR[];
X_ADDR[i] = ...;
我有这段C代码(对于MSP430平台,cl430
编译器):
void function(uint8_t * x){
// This variable is defined in the linker file as "X_ADDR = 0xE000;"
extern uint32_t X_ADDR;
uint16_t i = 0;
uint16_t size = 10;
uint32_t dst_addr = (uint32_t) &X_ADDR;
for (i=0; i < size; i++){
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
}
我的理解是这样的,但我猜这里是我错的地方:
*((uint8_t *) (dst_addr+i)) = *(x + i);
| | | |
V V V V
*((uint8_t *) (u32 + u16)) = *(u8*+u16);
*((uint8_t *) (u32)) = *(u8*);
*(u8*) = u8;
u8 = u8;
该平台是 16 位的,但它支持 20 位的扩展寻址模式。
对此有什么提示吗?应该怎么做呢?提前致谢
它反对整数dst_addr
到指针的转换,而不是uint8_t
$ gcc -c -Wall -W type.c
type.c: In function 'function':
type.c:11:12: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
^
和 clang 提供类似的:
$ clang -c type.c -W -Wall
type.c:11:12: warning: cast to 'uint8_t *' (aka 'unsigned char *') from smaller integer type 'unsigned int'
[-Wint-to-pointer-cast]
*((uint8_t *) (dst_addr+i)) = *(x+i); // <-- This line shows the warning
^
(clang 3.4.2; gcc 4.8.5)
从 int 转换为指针总是令人怀疑,而且我不确定是否有办法告诉编译器你是认真的,至少如果你打开所有警告(这是一个很好的做法) ).
您似乎在使用 64 位指针的 64 位编译器上得到了这个。将 32 位整数转换为 64 位指针是有问题且不可移植的。
使用专用于此目的的可移植整数类型来更正此问题:
uintptr_t dst_addr = 0x00FFABCD;
现在它可以在所有主流 64 位编译器上干净地编译。在 gcc 上试过,clang icc -std=c11 -Wextra -Wall -pedantic-errors
,没问题。
此外,访问绝对地址时,几乎肯定需要volatile
限定指针。
您正在将 32 位整数转换为 16 位指针。
为确保您的整数类型与指针大小相同,请使用 <stdint.h>
中的 uintptr_t
。
并且当您将 X_ADDR
视为字节数组时,最好这样声明它:
extern uint8_t X_ADDR[];
X_ADDR[i] = ...;