何时在C中需要转换void指针?

时间:2013-12-09 11:52:10

标签: c pointers casting void

我一直在关注Mitchell,Oldham和Samuel的高级Linux编程。我在pthreads一节中看到过一些关于void指针和转换的东西让我很困惑。

将参数传递给pthread_create(),它们不会将指针强制转换为void指针,即使这是函数所期望的。

pthread_create( &thread, NULL, &compute_prime, &which_prime );

此处, which_prime 的类型为 int

但是使用pthread_join从线程返回一个值,他们将变量转换为void指针。

pthread_join( thread, (void*) &prime );

此处, prime 的类型为 int

为什么在第二个实例中完成转换而不在第一个实例中完成转换?

5 个答案:

答案 0 :(得分:10)

第二个例子是一个很好的例子,说明为什么投射到void*通常是一个错误。它应该是

void *primep = ′  // no cast needed
pthread_join(thread, &primep);

因为pthread_joinvoid**作为其第二个参数。 void*仅确保错误通过编译器,因为void*会自动转换为void**

所以,当时,您需要转换为void*或返回:

  • 使用存储为整数的指针((u)intptr_t);
  • 将指针传递给具有不完整原型的函数并取void*(或采用不同类型的指针,并且void*);这通常意味着函数采用可变数量的参数,例如printf

答案 1 :(得分:9)

无需在C:

中转换为指向void的指针
  

6.3.2.3指针

     

1   指向 void 的指针可以转换为指向任何不完整或对象的指针   类型。指向任何不完整或对象类型的指针可能会转换为指向 void 的指针   又回来了;结果应该等于原始指针。


唯一的例外是

  • 使用"%p"转化说明符打印指针时,因为它仅为void *定义。
  • 将指针的值从intptr_tuintptr_t复制回void *

答案 2 :(得分:4)

在C中,隐式地从任何指针类型转换为void *,反之亦然。 在第二个例子中没有必要进行演员表。

(注意,在C ++中,任何指向void *的指针也是隐式执行的(函数指针和函数成员/方法指针除外,它们不能转换为void *),但是回退需要显式转换。)

答案 3 :(得分:2)

根据documentation,

int pthread_join(pthread_t thread, void **retval);

因此,pthread_joinpointer to void*作为其第二个参数。这是因为,

  

在pthread_join中,您将获取传递给pthread_exit的地址   完成的线程。如果只传递一个普通指针,则传递给它   值,这样你就无法改变指向的位置。有能力去   更改传递给pthread_join的指针的值,它必须是   作为指针本身传递,即指向指针的指针。

现在,对于你的问题," 为什么在第二个实例中而不是在第一个实例中完成转换?" 在第一个实例中,即pthread_create,它期望void*作为其第四个参数。因此,传递&which_prime将隐式转换为void*

在第二个例子中,即pthread_join,它需要一个void**,我们正在那里传递&prime。所以,编译器会抱怨。因此,为了绕过该错误,作者传递void*的演员表,该演员表将自动转换为void**

但这不是一个好的解决方案。

解决方案::

void* prime ; // make prime as void*
pthread_join( thread, &prime );
printf( "%" PRIxPTR "\n", (intptr_t)prime ) ; 
// intptr_t instead of int to get an integer type 
// that's the same size as a pointer

答案 4 :(得分:1)

我相信其他referenced中的相同代码questions

第二个链接中的答案解释了:

  

它无效。如果sizeof(int)==,它恰好会起作用   sizeof(void *),发生在许多系统上。

     

void *仅保证能够保存指向数据的指针   对象。

     

这是关于这个主题的C FAQ。

引用文字:

  

如何将整数转换为指针和从指针转换?我可以暂时吗?   将整数填充到指针中,反之亦然?

     

指针到整数和整数到指针的转换是   实现定义(见问题11.33),不再存在   任何保证指针可以转换为整数和返回,   没有改变

     

强制指针指向整数或整数成指针,从来没有   一直很好的做法