保留现场
void* foo(void *dst, ...) {
// some code
unsigned int offset = (unsigned int) dst % 8; // warning here!
// some code continue...
}
写驱动程序时经常会直接对地址进行修改,配置寄存器的值,也会将地址的值作为数据进行传递,这就会遇到一个问题,指针强转成整型,类型不匹配数据丢失的问题。
探究原因
出现这个警告的原因是,将void*
类型强转成unsigned int
是不可移植的。什么叫不可移植呢?
我们知道指针类型,在 32 位系统下是 4 字节,在 64 位系统下是 8 字节,而unsigned int
不管在什么系统下都是是 4 字节,所以,如果将void*
类型强转成unsigned int
,在 64 位系统下就没有足够的空间保存真正的数据。
解决方法
粗暴地用double
来接收
先接收,再截断:
void* foo(void *dst, ...) {
// some code
unsigned int offset = (unsigned int)(unsigned double) dst % 8; // warning here!
// some code continue...
}
uintptr_t
uintptr_t
保证足够宽,以便将 void*
转换为 uintptr_t
并再次返回将产生原始指针值。还有一个类型 intptr_t
,它是有符号的;
#include <stdint.h>
// 或者 <inttypes.h>
void* foo(void *dst, ...) {
// some code
unsigned int offset = (uintptr_t) dst % 8; // warning here!
// some code continue...
}