2012-11-25 113 views
4

我正在編寫套接字編程..我的代碼按照我希望的方式執行,我可以使用它。但它給我一個編譯警告。警告:從指針投射到不同大小的整數

我編譯使用

gcc server1.c -o server1 -lpthread 

我得到警告

warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] 

這個錯誤出現以下代碼

int newsockfd; 
newsockfd = (int)newsockfdd; //this line 

而且我使用newsockfdd(這是INT )在下面的代碼塊中:

if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0) 
    { 
     perror("Thread create error"); 
    } 

正如你可能會說,代碼寫得不好(我正在努力使它更好)。我知道這個警告是因爲與int的大小有關。但我真的不知道如何解決它。我把(使用intptr_t)在聲明在pthread_create之前,它顯示在該行警告,但那個時候的警告是

warning: cast to pointer from integer of different size [-Wint-to-pointer-cast] 

好像應該有一個簡單的解決這個?但我找不到它。我使用Ubuntu 64位。這是警告的原因嗎?

+0

嗯,考慮到你在從'(void *)newsockfdd'獲得''void''newsockfdd'之前的警告,看起來不太可能''從指針轉換爲不同大小的整數警告實際上來自指定行。 –

+0

除非......'serverThread'和'newsockfdd'中的那條線是'serverThread'接收的參數嗎?那麼它會很清楚。 –

+0

@DanielFischer是的..我把它作爲參數傳遞給serverThread。像這樣:void * serverThread(void * newsockfdd)。那麼,什麼是錯的? – user1825770

回答

6

如已經建立的意見,情況(模重命名以避免newsockfdd混淆發生作爲傳遞的參數或接收的參數)

void *serverThread(void *arg) { 
    // ... 
    int newsockfd = (int)arg; 
    // ... 
} 

main(或從那裏調用的函數)

// ... 
int newsockfdd = whatever; 
// ... 
if (pthread_create(&threadID[i++], NULL, serverThread, (void *)(intptr_t)newsockfdd) != 0) 
// .. 

所以當int newsockfdd作爲參數傳遞給serverThread,它被轉換爲void*。最初,演員表是直接演員,但插入到intptr_t的中間演員已插入,以刪除有關cast to pointer from integer of different size的警告。

而在serverThread,接收void*被轉換爲int,導致有關cast from pointer to integer of different size警告。

通過在intptr_t中插入中間轉換名,也可能會刪除該警告。

但是,儘管標準允許鑄造整數爲指針,反之亦然,結果是實現定義的,沒有保證int -> void* -> int往返(雖然在標準的一個腳註說

映射用於將指針轉換爲整數或整數的指針旨在使其與執行環境的尋址結構一致。

所以可能它將往返工作按預期在這種情況下 - 但它可能會無法正常工作[只爲足夠小的絕對值值]如果void*的尺寸比小整數類型[在32位系統上考慮long long -> void* -> long long])。

適當解決方法是避免整數和指針之間的鑄造,

void *serverThread(void *arg) { 
    // ... check that arg isn't NULL 
    int newsockfd = *(int *)arg; 
    // ... 
} 
severThread

,鑄所接收的指針適當類型的指針,讀出指針指向的值,並且在main

if// ... 
int newsockfdd = whatever; 
// ... 
if (pthread_create(&threadID[i++], NULL, serverThread, &newsockfdd) != 0) 

通過地址newsockfdd

一個告誡:如果serverThread被從多個地方調用,所有這些地方的電話需要修復。

+0

主要建議傳遞一個局部變量的地址作爲參數。這是一個bug,如果main在serverThread()執行之前退出,並且後者試圖取消引用地址(這不再是有效的地址,因爲當main退出時newsockfdd將被釋放),程序將崩潰。更好的是中間轉換,或者傳遞靜態變量的地址而不是本地(本地)地址。 – davec

+0

嗯,我有一個印象,如果'main'退出,它會將所有'pthread_create'd線程與它(但它應該加入生成的線程)。 –

+0

我不認爲這是保證,但我可能是錯的。無論如何,儘管它比對不起更安全。考慮創建線程是否在main調用的輔助函數中完成。然後無論主要是否等待孩子退出,都會出現問題。按照經驗法則,最好不要將本地地址傳遞給其他線程...... – davec

相關問題