簡體   English   中英

c89: 將 int 轉換為 void* 並返回

[英]c89: Convert an int to void* and back

首先,這不是欺騙:

將 int 強制轉換為 void 指針並再次返回 int 是否安全?

問題的不同之處在於:我只使用 void* 來存儲 int,但我從未真正將它用作 void*。

所以問題真的歸結為:

是否保證 void * 至少與 int 一樣寬

我不能使用 intptr_t,因為我使用的是 c89 / ANSI C。

編輯

在 C99 的 stdint.h ( gcc 版本)中,我看到以下內容:

/* Types for `void *' pointers.  */
#if __WORDSIZE == 64
# ifndef __intptr_t_defined
typedef long int        intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned long int   uintptr_t;
#else
# ifndef __intptr_t_defined
typedef int         intptr_t;
#  define __intptr_t_defined
# endif
typedef unsigned int        uintptr_t;
#endif

我能不能只是簡單地安裝類似的東西並期望它能夠工作? 看起來強制轉換應該起作用,因為所有 intptr_t 都是整數類型的 typedef ...

不,這不能保證是安全的。

C99 標准有這樣的說法(第 6.3.2.3 節):

integer 可以轉換為任何指針類型。 除非前面指定,結果是實現定義的,可能沒有正確對齊,可能不指向引用類型的實體,並且可能是陷阱表示。

任何指針類型都可以轉換為 integer 類型。 除非前面指定,結果是實現定義的。 如果結果無法以 integer 類型表示,則行為未定義。 結果不必在任何 integer 類型的值范圍內。

我非常有信心 C99 之前的版本不會有任何不同。

FreeRTOS 將 Timer_t 中的計時器 ID 存儲為 void* pvTimerID。 因此,當使用 this 作為存儲空間而不是指向某個東西的指針時,有必要將它轉換為可以用作數組索引的東西,例如。

因此要讀取存儲為 void* 的 id:

void* pvId = pxTimer->pvTimerID; int index = (int)(pvId - NULL);

有一個C 常見問題解答:我可以暫時將 integer 填充到指針中,反之亦然? .

最明確的答案是:不,這不安全,避免它並繼續它。 但是POSIX要求這是可能的。 所以它在符合 POSIX 的系統上安全的。

這是一個便攜式替代方案。

static const char dummy[MAX_VALUE_NEEDED];
void *p = (void *)(dummy+i); /* cast to remove the const qualifier */
int i = p-dummy;

當然,如果您需要較大的值,它可能會浪費大量的虛擬地址空間,但如果您只想傳遞小整數,這是將 integer 值存儲在void *中的 100% 可移植且干凈的方式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM