背景: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 }