是否可以直接将 void 指针类型转换为 long 而不会造成麻烦?下面是我从代码 here 中提取的一个小代码片段(页面Pthread Joining部分下的示例)。
{
void *status;
long t;
rc = pthread_create(&thread[t], &attr, BusyWork, (void *)t);
rc = pthread_join(thread[t], &status);
printf("Main: completed join with thread %ld having a status of %ld\n",t,(long)status);
}
如this manual page表示 pthread_join() 将目标线程的退出状态(即目标线程提供给 pthread_exit() 的值)复制到 *retval(本例中为 *status)指向的位置。但在我提到的程序中,状态并不指向任何位置。那这个程序怎么还能运行呢?
其次,据我所知,状态不能保存长值,那么类型转换状态如何给我们一个长值而不是地址?
最佳答案
快速回答:不,使用 intptr_t
长答案: long 不能保证适合 void *。在某些系统(特别是 64 位 Intel Linux 机器)上,它可以工作,因为 void * 和 long 都是 64 位数量,并且 Intel 处理器没有其他类型差异。在其他机器上,例如 32 位 Intel Linux,它将无法工作,因为在这些机器上 long 是 64 位,而 void * 32 位。更多奇特的机器具有不同的属性。
支持 int <-> 指针转换的标准类型是 intptr_t,可在 stdint.h 中找到。根据POSIX 程序员手册:
The following type designates a signed integer type with the property that any valid pointer to void can be converted to this type, then converted back to a pointer to void, and the result will compare equal to the original pointer: intptr_t
因此 intptr_t 是一个未指定长度的有符号整数类型,保证支持 void * 之间的转换。还有unsigned uintptr_t。
Here is the definition of intptr_t in glibc 。正如你所看到的,在64位机器上intptr_t和long确实是相同的类型。
关于c - 将 void* 类型转换为 long,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36527579/