在同一条线上投两次

我在项目中看到了这段代码。

b的类型是void*

 void *b = ...; int a = (int) (unsigned long) b; 

这条线是没有意义的吗? 我的意思是,它在所有情况下都与a = (int) b相同吗?

这可能避免了64位Unix系统上的编译器警告,其中unsigned long是64位数量,因此大到足以容纳指针,但int是32位数量,不足以容纳指针。 转换为(unsigned long)保留地址的所有位; 后续的int抛出地址的高32位,但默认情况下不会收到警告。

展示:

 int main(void) { void *b = (void *)0x12345678; int a = (int)(unsigned long)b; int c = (int)b; return a + c; } $ gcc -O3 -g -std=c99 -Wall -Wextra -c ar.c ar.c: In function 'main': ar.c:5:15: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] $ 

在Mac OS X 10.8.4上使用GCC 4.7.1,默认为64位编译。

有趣的是推测将对“地址的一部分”值做什么。

直接类型转换为指向较小类型的指针,如果在x64位环境下,可能会导致某些编译器(如Clang)的编译错误。

例如:

  void *p = GetSomeAddress; int i = (int)p; //error on compilers like Clang. 

解决方案是:

 int i = (int)(unsigned long)p; 

要么

 int i = (int)(long)p; 

这是因为,在Unix上,在LP64模型下,long是64位。

在这种情况下,您需要彻底查看为什么需要从指向int或其他较小类型的类型转换,这可能导致数据丢失。

这个问题也可以帮到你。 在64位计算机上编译32位代码时,如何处理“从’void *’转换为’int’失去精度”?

我也在我的项目中看到了这一点。

对于我的情况,’b’的内容由用于进程间通信的其他源/中间件填充。

一旦’b’被填充,程序将获得’b’的内容,并将其转换为正确的字段’a’。 然后应用程序使用’a’进行处理。

我的项目使用char *而不是void *。