什么时候在C中需要转换void指针?

Amo*_*eba 20 c pointers casting void

我一直在关注米切尔,奥尔德姆和塞缪尔的高级Linux编程.我在pthreads一节中看到过一些关于void指针和转换的东西让我很困惑.

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

pthread_create( &thread, NULL, &compute_prime, &which_prime );
Run Code Online (Sandbox Code Playgroud)

这里,which_prime的类型为int.

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

pthread_join( thread, (void*) &prime );
Run Code Online (Sandbox Code Playgroud)

这里,prime再次为int类型.

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

Fre*_*Foo 10

第二个例子是一个很好的例子,说明为什么施法void*通常是一个错误.它应该是

void *primep = ′  // no cast needed
pthread_join(thread, &primep);
Run Code Online (Sandbox Code Playgroud)

因为pthread_join将a void**作为其第二个参数.在void*只有确保该bug通过编译,因为void*转换为void**自动.

所以,当这样做,你需要转换为void*或回:

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


alk*_*alk 9

无需void在C中转换或转到指针:

6.3.2.3指针

1指向void的指针可以转换为指向任何不完整或对象类型的指针.指向任何不完整或对象类型的指针可能会转换为指向void的指针 并再次返回; 结果应该等于原始指针.


唯一的例外是

  • 使用"%p"转换说明符打印指针时,仅为其定义void *.
  • 将指针的值从一个intptr_t或从一个或多个复制uintptr_t到一个时void *.


Asa*_*saf 7

在 C 中,从任何指针类型转换为 void* 和反之亦然是隐式完成的。在第二个示例中不需要演员表。

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