指標的數字值
使用 reinterpret_cast
將指標轉換為整數的結果是實現定義的,但“……對於那些知道底層機器的定址結構的人來說,意圖是不足為奇的。”
int x = 42;
int* p = &x;
long addr = reinterpret_cast<long>(p);
std::cout << addr << "\n"; // prints some numeric address,
// probably in the architecture's native address format
同樣,通過從整數轉換獲得的指標也是實現定義的。
將指標儲存為整數的正確方法是使用 uintptr_t
或 intptr_t
型別:
// `uintptr_t` was not in C++03. It's in C99, in <stdint.h>, as an optional type
#include <stdint.h>
uintptr_t uip;
Version >= C++ 11
// There is an optional `std::uintptr_t` in C++11
#include <cstdint>
std::uintptr_t uip;
對於定義 uintptr_t
(C99 標準,6.3.2.3),C++ 11 引用 C99:
一個無符號整數型別,其屬性是任何到
void
的有效指標都可以轉換為這種型別,然後轉換回指向void
的指標,結果將等於原始指標。
同時,為廣大現代的平臺上,你可以假設一個平面地址空間和 uintptr_t
算術相當於對 char *
算術,這是完全有可能實現轉換 void *
到 uintptr_t
只要改造時進行任何改造可以逆轉從 uintptr_t
回到 void *
時。
技術性
-
在符合 XSI 的(X / Open System Interfaces)系統上,需要
intptr_t
和uintptr_t
型別,否則它們是可選的。 -
在 C 標準的含義內,函式不是物件; C 標準不保證
uintptr_t
可以儲存一個函式指標。無論如何,POSIX(2.12.3)
一致性要求:所有函式指標型別應與 void 指向的型別指標具有相同的表示形式。將函式指標轉換為 void *不得改變表示。這種轉換產生的 void *值可以使用顯式轉換轉換回原始函式指標型別,而不會丟失資訊。
-
C99§7.18.1:
當 typedef 名稱僅在缺少或存在初始 u 時定義時,它們應表示 6.2.5 中描述的相應的有符號和無符號型別; 提供這些相應型別之一的實現也應提供另一種。
uintptr_t
可能是有意義的,如果你想對指標的位做一些你不能用有符號整數明智地做的事情。