铸造长到(void *)通过

时间:2012-09-05 05:21:20

标签: c casting void-pointers

从LLNL读取pthread tutorial我点击以下示例代码

/******************************************************************************
* FILE: hello.c
* DESCRIPTION:
*   A "hello world" Pthreads program.  Demonstrates thread creation and
*   termination.
* AUTHOR: Blaise Barney
* LAST REVISED: 08/09/11
******************************************************************************/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#define NUM_THREADS 5

void *PrintHello(void *threadid)
{
   long tid;
   tid = (long)threadid;
   printf("Hello World! It's me, thread #%ld!\n", tid);
   pthread_exit(NULL);
}

int main(int argc, char *argv[])
{
   pthread_t threads[NUM_THREADS];
   int rc;
   long t;
   for(t=0;t<NUM_THREADS;t++){
     printf("In main: creating thread %ld\n", t);
     rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);
     if (rc){
       printf("ERROR; return code from pthread_create() is %d\n", rc);
       exit(-1);
       }
     }

   /* Last thing that main() should do */
   pthread_exit(NULL);
}

我可以看到为什么 long是通过void *投射的(好像它不是,你传递一个指向t的指针线程是乱码),我的问题是,这应该被视为犹太教并始终有效吗?或者这是一个快速入侵,以获得最简单的线程工作示例?这是标准的C事吗?

2 个答案:

答案 0 :(得分:4)

不,就ISO C标准而言,它不是严格 Kosher,因为无法保证指针足够宽以容纳长。

犹太洁食解决方案是将指针传递给long,或者每个线程有一个唯一的长(例如数组中的一个)或者具有线程间通信(例如条件变量)创建者线程和创建的线程之间,以便后者可以在前者被允许更改它以进行下一个线程创建之前进行复制。

但是,它并非严格意义上的犹太教并不意味着它不会在特定的实施中起作用。如果您可以保证void*long之间的演员表不会丢失任何信息,那么它可能会正常工作。

来自C11 6.3.2.3 Pointers(虽然它与C99基本没有变化):

  

整数可以转换为任何指针类型。除非事先指明,否则   结果是实现定义的,可能没有正确对齐,可能不指向   引用类型的实体,可能是陷阱表示。

     

任何指针类型都可以转换为整数类型。除非事先指明,否则   结果是实现定义的。如果结果无法以整数类型表示,   行为未定义。结果不必在任何整数的值范围内   类型。

答案 1 :(得分:0)

仅适用于32位系统,在64位系统的情况下,long的大小为32位,但void *的大小为64位。