背景:miduo 源碼中遇到如下語句:
uintptr_t v = reinterpret_cast<uintptr_t>(p);
以上 p 的類型是void *
現在他的底層二進制提供了新的解釋 解釋為uintptr_t的類型。
那uintptr_t究竟是個什么類型呢?
在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適配相應的數據類型。 另外,如注釋所言,定義這兩個數據類型別名也是為了“void *”指針。 在C語言中,任何類型的指針都可以轉換為void *類型,並且在將它轉換回原來的類型時不會丟失信息。
實驗代碼:
#include <iostream>
#include <stdio.h>
#include <stdint.h>
using namespace std;
void func()
{
cout<<"xxxx"<<endl;
}
int main()
{
uintptr_t ptr = reinterpret_cast<uintptr_t>(&func);
//unsigned int ptr = reinterpret_cast<uintptr_t>(&func);
printf("%p %lu\n", (&func), ptr);
//printf("%p\n", (&func));
//cout<<ptr<<" "<<(&func)<<endl;
return 0;
}
實驗結果:
➜ t6 ./test1 0x5584b380690a 94028435581194
這里的 94028435581194 轉換成16進制就是 0x5584b380690a
這里說明uintptr_t就是unsigned long int
如果是:
unsigned int ptr = reinterpret_cast<uintptr_t>(&func);
printf("%p %u\n", (&func), ptr);
輸出的結果為:
➜ t6 ./test1 0x56500dabe90a 229370122
后面的229370122轉換為16進制為dabe90a 由此懷疑我的電腦為小端機。
下面驗證一下我的電腦為小端機。
➜ t6 ./test1
0x55c6558a597a 1435130234
122
122 對應的16進制為7a,由此地址最小位置和數字的最小位重疊,小端機實錘。
實驗代碼:
1 #include <iostream> 2 #include <stdio.h> 3 #include <stdint.h> 4 using namespace std; 5 6 void func() 7 { 8 cout<<"xxxx"<<endl; 9 } 10 11 int main() 12 { 13 //uintptr_t ptr = reinterpret_cast<uintptr_t>(&func); 14 unsigned int ptr = reinterpret_cast<uintptr_t>(&func); 15 printf("%p %u\n", (&func), ptr); 16 char *p = (char *)(&ptr); 17 printf("%u\n", (*p)); 18 //printf("%p\n", (&func)); 19 //cout<<ptr<<" "<<(&func)<<endl; 20 return 0; 21 }
