[英]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.