簡體   English   中英

什么是 uintptr_t 數據類型

[英]What is uintptr_t data type

什么是uintptr_t ,它可以用來做什么?

首先,在提出問題時, uintptr_t不在 C++ 中。 它在 C99 中,在<stdint.h> ,作為可選類型。 許多 C++03 編譯器確實提供了該文件。 它也在 C++11 中,在<cstdint> ,它也是可選的,並且它指的是 C99 的定義。

在 C99 中,它被定義為“一種無符號整數類型,其特性是任何指向 void 的有效指針都可以轉換為此類型,然后轉換回指向 void 的指針,並且結果將與原始指針相等”。

把這當作它所說的意思。 它沒有說明大小。

uintptr_t可能與void*大小相同。 它可能更大。 可以想象它會更小,盡管這樣的 C++ 實現方法有悖常理。 例如,在void*為 32 位,但僅使用 24 位虛擬地址空間的某些假設平台上,您可以擁有滿足要求的 24 位uintptr_t 我不知道為什么實現會這樣做,但標准允許這樣做。

uintptr_t是一種能夠存儲數據指針的無符號整數類型。 這通常意味着它與指針的大小相同。

它在 C++11 和更高版本的標准中可選地定義。

需要一個可以保存架構指針類型的整數類型的一個常見原因是對指針執行整數特定的操作,或者通過將指針的類型提供為整數“句柄”來隱藏指針的類型。

它是一個與指針大小完全相同的無符號整數類型。 每當您需要用指針做一些不尋常的事情時 - 例如反轉所有位(不要問為什么),您將它uintptr_tuintptr_t並將其作為通常的整數uintptr_t操作,然后轉換回來。

“什么是uintptr_t數據類型”部分已經有很多很好的答案。 我將嘗試解決“它可以用來做什么?” 參與這篇文章。

主要用於指針的按位運算。 請記住,在 C++ 中,不能對指針執行按位運算。 原因參見為什么不能對 C 中的指針進行按位運算,有沒有辦法解決這個問題?

因此,為了對指針進行按位運算,需要將指針轉換為 unitpr_t 類型,然后執行按位運算。

這是我剛剛編寫的一個函數示例,用於按位異或將 2 個指針存儲在 XOR 鏈表中,以便我們可以像雙向鏈表一樣在兩個方向上遍歷,但不會在每個節點中存儲 2 個指針.

 template <typename T>
 T* xor_ptrs(T* t1, T* t2)
 {
     return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(t1)^reinterpret_cast<uintptr_t>(t2));
  }

冒着獲得另一個死靈法師徽章的風險,我想為uintptr_t (甚至intptr_t )添加一個非常好的用途,那就是編寫可測試的嵌入式代碼。

我主要編寫針對各種 arm 和當前 tensilica 處理器的嵌入式代碼。 它們具有不同的本機總線寬度,並且 Tensilica 實際上是一種哈佛架構,具有不同寬度的單獨代碼和數據總線。

我對我的大部分代碼使用測試驅動的開發風格,這意味着我對我編寫的所有代碼單元進行單元測試。 在實際目標硬件上進行單元測試很麻煩,因此我通常使用 Ceedling 和 GCC 在 Windows 或 Linux 中的基於 Intel 的 PC 上編寫所有內容。

話雖如此,許多嵌入式代碼都涉及位處理和地址操作。 我的大多數 Intel 機器都是 64 位的。 因此,如果您要測試地址操作代碼,則需要一個通用對象來進行數學運算。 因此,在您嘗試部署到目標硬件之前, uintptr_t為您提供了一種獨立於機器的調試代碼的方式。

另一個問題是對於某些機器甚至某些編譯器上的內存模型,函數指針和數據指針的寬度不同。 在這些機器上,編譯器甚至可能不允許在兩個類之間進行轉換,但uintptr_t應該能夠保持其中任何一個。

- 編輯 -

@chux 指出,這不是標准的一部分,函數也不是 C 中的對象。但是它通常可以工作,而且由於很多人甚至不知道這些類型,我通常會發表評論來解釋這個技巧。 uintptr_t上的 SO 中的其他搜索將提供進一步的解釋。 我們還在單元測試中做一些我們在生產中永遠不會做的事情,因為打破東西是好的。

暫無
暫無

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

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