繁体   English   中英

无效说明*

[英]clarification on void *

由于我们只能将一个指针强制转换为另一个指针,因此下面的代码中“(void *)t和(int)threadid”的工作原理如何? 我们不应该用&t代替t吗?

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);
}

为了进一步说明我的观点,C明确提供了指针可以转换为整数的方法, 反之亦然 除了值为0整数常量(可靠地转换为NULL指针)外,结果是实现定义的。 这样的转换仅需按照以下我的附录中所述是可逆的。

但是,实际上,对于某些n而言 ,指针表示形式通常等效于n位无符号整数。 在这些情况下,通常情况下,您可以安全地在指针和足够宽度的整数之间来回转换而不会丢失信息。 即使您可能无法安全地执行指针->整数->指针,也更有可能(但仍不能保证)从(不是太宽的整数)到指针往返并返回而不会丢失信息。 一致的C实现将记录所有实现定义的行为(包括这些行为)的详细信息。

您展示的程序取决于此类转换; 它们将在许多环境中工作,但是它们是否确实取决于使用的C实现。 如您建议的那样,可以通过传递真正的指针(并将其用作一个指针)来避免这种实现依赖性。

更新后添加:

在注释中,@IanAbbott引发了类型intptr_t ,C2011对此描述如下:

有符号整数类型,具有以下属性:任何有效的指向void的指针都可以转换为该类型,然后再转换回指向void的指针,结果将与等于可选原始指针的结果进行比较。

-C2011,7.20.1.4

提供此类型的合格实现将确保其有关转换的行为符合规定,但由于实现是可选的,因此不与实现指定的指针/整数转换的性质相冲突(已进行了描述)在C2011 6.3.2.3/3-6中)。 对于涉及其他整数类型(或其他指针类型)的转换,即使提供这种类型的实现也根本不承担任何义务。

还要注意,尽管intptr_tuintptr_t (如果可用)提供了从指针到整数再回到指针的往返转换,但就标准而言,它的规定与整数到指针再回到整数无关。

这里,

 rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t);

最后一个参数中的强制类型转换longt )强制转换为void * (这是传递给线程函数的参数)。 进行pthread_create()是因为pthread_create()接受void *作为最后一个参数。

值再次从void *转换回long值:

   tid = (long)threadid;

但是此转换完全是实现定义的,并且有可能被允许作为陷阱表示(因此未定义 )。 因此,这种转换并不安全。

相反,您可以使用一个临时数组:

  long arr[NUM_THREADS];

  for(t=0;t<NUM_THREADS;t++){
     printf("In main: creating thread %ld\n", t);
     arr[t] = t; 
     rc = pthread_create(&threads[t], NULL, PrintHello, &arr[t]);
     ...

但这涉及确保在线程接收该值之前,数组arr生命周期没有结束。 这可以通过在主线程中使用pthread_join()或使用malloc指针(而不是使用本地数组arr )或使用具有静态存储持续时间的数组(例如使arr全局)来完成。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM