指標的數字值

使用 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_tintptr_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_tuintptr_t 型別,否則它們是可選的

  • 在 C 標準的含義內,函式不是物件; C 標準不保證 uintptr_t 可以儲存一個函式指標。無論如何,POSIX(2.12.3) 一致性要求:

    所有函式指標型別應與 void 指向的型別指標具有相同的表示形式。將函式指標轉換為 void *不得改變表示。這種轉換產生的 void *值可以使用顯式轉換轉換回原始函式指標型別,而不會丟失資訊。

  • C99§7.18.1:

    當 typedef 名稱僅在缺少或存在初始 u 時定義時,它們應表示 6.2.5 中描述的相應的有符號和無符號型別; 提供這些相應型別之一的實現也應提供另一種。

    uintptr_t 可能是有意義的,如果你想對指標的位做一些你不能用有符號整數明智地做的事情。