簡體   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