c語言: Noncompliant Code Example(不兼容的代碼示例) The size of a pointer can be greater than the size of an integer, such as in an implementation where pointers are 64 bits and unsigned integers are 32 bits. This code example is noncompliant on such implementations because the result of converting the 64-bit ptr cannot be represented in the 32-bit integer type: void f(void) { char *ptr; /* ... */ unsigned int number = (unsigned int)ptr; /* ... */ } Compliant Solution(兼容的代碼示例) Any valid pointer to void can be converted to intptr_t or uintptr_t and back with no change in value (seeINT36-EX2). The C Standard guarantees that a pointer to void may be converted to or from a pointer to any object type and back again and that the result must compare equal to the original pointer. Consequently, converting directly from a char * pointer to a uintptr_t, as in this compliant solution, is allowed on implementations that support the uintptr_t type. #include void f(void) { char *ptr; /* ... */ uintptr_t number = (uintptr_t)ptr; /* ... */ } 使用intptr_t和uintptr_t才是兼容的,,就死一套代碼同時兼容32位和64位的操作系統(tǒng),。
intptr_t和uintptr_t 這兩個數據類型是ISO C99定義的,具體代碼在linux平臺的/usr/include/stdint.h頭文件中,。 該頭文件中定義intptr_t和uintptr_t這兩個數據類型的代碼片段如下: /* Types for `void *' pointers. */ 在64位的機器上,,intptr_t和uintptr_t分別是long int、unsigned long int的別名,;在32位的機器上,,intptr_t和uintptr_t分別是int、unsigned int的別名,。 那么為什么要用typedef定義新的別名呢,?我想主要是為了提高程序的可移植性(在32位和64位的機器上)。很明顯,,上述代碼會根據宿主機器的位數為intptr_t和uintptr_t適配相應的數據類型,。
c++語言: reinterpret_cast<type-id> (expression) type-id 必須是一個指針、引用,、算術類型,、函數指針或者成員指針。它可以把一個指針轉換成一個整數,,也可以把一個整數轉換成一個指針(先把一個指針轉換成一個整數,,再把該整數轉換成原類型的指針,還可以得到原先的指針值)。 type-id是轉換后的類型,,expresion是轉換前的,。
static_cast 與 reinterpret_cast reinterpret_cast是為了映射到一個完全不同類型的意思,這個關鍵詞在我們需要把類型映射回原有類型時用到它,。我們映射到的類型僅僅是為了故弄玄虛和其他目的,,這是所有映射中最危險的。(這句話是C++編程思想中的原話) static_cast和reinterpret_cast的區(qū)別主要在于多重繼承,,比如
那么對于以下代碼:
前兩個的輸出值是相同的,,最后一個則會在原基礎上偏移4個字節(jié),,這是因為static_cast計算了父子類指針轉換的偏移量,,并將之轉換到正確的地址(c里面有m_a,m_b,轉換為B*指針后指到m_b處),,而reinterpret_cast卻不會做這一層轉換,。 總結:reinterpret_cast用于指針和整型之間的轉換是沒有問題,如果用于子類和父類類型方面的轉換,,會有問題,。如果需要在子類和父類指針之間的轉換,要用static_cast,。 |
|