intprt_t

转载链接:http://blog.csdn.net/justlinux2010/article/details/7490420


最近在看nginx源码,看到有一个类型intptr_t,没有见过,google了一下,有人说是指针类型,但是看nginx源码中对该类型变量的使用,好像不是指针类型。

[cpp]  view plain  copy
  1. static ngx_int_t  
  2.  667 ngx_get_options(int argc, char *const *argv)  
  3.  668 {  
  4.  669     u_char     *p;  
  5.  670     ngx_int_t   i;  
  6.  671   
  7.  672     for (i = 1; i < argc; i++) {  
  8.  673   
  9.  674         p = (u_char *) argv[i];  
  10.  675   
  11.  676         if (*p++ != '-') {  
  12.  677             ngx_log_stderr(0, "invalid option: \"%s\"", argv[i]);  
  13.  678             return NGX_ERROR;  
  14.  679         }  
  15.  680   
  16.  681         while (*p) {  
  17.  682   
  18.  683             switch (*p++) {  
  19.  684   
  20.  685             case '?':  
  21.  686             case 'h':  
  22.  687                 ngx_show_version = 1;  
  23.  688                 ngx_show_help = 1;  
  24.  689                 break;  
其中ngx_int_t的定义如下:
[cpp]  view plain  copy
  1. 78 typedef intptr_t        ngx_int_t;  


于是在Linux的头文件中查找这个类型的定义,在/usr/include/stdint.h这个头文件中找到了这个类型的定义(不知道怎么在这里插入图片,所以使用文字):

                           

[cpp]  view plain  copy
  1. 117 /* Types for `void *' pointers.  */  
  2. 118 #if __WORDSIZE == 64  
  3. 119 # ifndef __intptr_t_defined  
  4. 120 typedef long int        intptr_t;  
  5. 121 #  define __intptr_t_defined  
  6. 122 # endif  
  7. 123 typedef unsigned long int   uintptr_t;  
  8. 124 #else  
  9. 125 # ifndef __intptr_t_defined  
  10. 126 typedef int         intptr_t;  
  11. 127 #  define __intptr_t_defined  
  12. 128 # endif  
  13. 129 typedef unsigned int        uintptr_t;  
  14. 130 #endif  

很明显intptr_t不是指针类型,但是上边的一句注释(/* Types for `void *' pointers. */)让人很疑惑。既然不是指针类型,但是为什么说类型是为了“void *”指针?

又查了一下在《深入分析Linux内核源码》中找到了答案,原文描述如下

尽管在混合不同数据类型时你必须小心, 有时有很好的理由这样做. 一种情况是因为内存存取, 与内核相关时是特殊的. 概念上, 尽管地址是指针, 内存管理常常使用一个无符号的整数类型更好地完成; 内核对待物理内存如同一个大数组, 并且内存地址只是一个数组索引. 进一步地, 一个指针容易解引用; 当直接处理内存存取时, 你几乎从不想以这种方式解引用. 使用一个整数类型避免了这种解引用, 因此避免了 bug. 因此, 内核中通常的内存地址常常是 unsigned long, 利用了指针和长整型一直是相同大小的这个事实, 至少在 Linux 目前支持的所有平台上.

因为其所值的原因, C99 标准定义了 intptr_t 和 uintptr_t 类型给一个可以持有一个指针值的整型变量. 但是, 这些类型几乎没在 2.6 内核中使用




转载来源:http://blog.csdn.net/menzi11/article/details/9322251

C++标准没有规定size_t , uintptr_t , intptr_t, int 这几个东西的byte数,所以任何确定地说这几个东西没区别,或者

确定地说这几个东西占XX个bit的行为都是耍流氓. 那么这几个东西有什么区别呢? 


int : 这个不用说了吧

size_t : 在当前平台下可能出现的最大数组尺寸.size_t必须是个unsigned但没有规定这个数和int的关系.

这个数在MSVC下是typedef unsigned int size_t, 但不要认为size_t 就是uint.

C++标准只规定了size_t 的最大值在当前目标平台(或者编译器)下一定能容纳的数组的最大尺寸. 假如我们有个平台,最大

数组尺寸为2^32 bit,那么size_t 的bit数可能是32,33,34.... 但不会小于32. 因为他必须能够表示当前平台下最大的数组尺寸那个值.

它和unsigned int的关系就是它们根本没有关系. 在某个目标平台下, unsigned int 没准是256个bit,而size_t 是16bit,这也是可能的.


intptr_t ,uintptr_t : 表示当前平台下能够安全地对指针进行转型的整型变量. 有些时候,我们不得不对一些指针进行一些整型转换

来执行一些指针类型无法操作的功能. 会写这样的代码: 

[cpp]  view plain  copy
  1. float* p=new float[...];  
  2. //.........................  
  3. int a=(int)p;  
这是不安全的,因为C++标准没有规定int类型一定能够容纳float*类型的全部值. 例如在某个特定平台下, float* 可能占4byte,但int只占2byte.

比较安全的转换是:

[cpp]  view plain  copy
  1. float* p=new float[...];  
  2. //.........................  
  3. intptr_t a=(intptr_t)p;  
  4. uintptr_t a2=(uintptr_t)p;  
此时是相对安全的,因为intptr_t和uintptr_t和float* 所占byte数是一样的.

intptr_t 和uintptr_t 显然是一个有符号一个无符号,但实际上我认为这俩没什么区别,因为有符号和无符号对加减法,求余来说计算出来的是一样的数值.

至于乘除法......我实在想不出来对一个指针转过来的整型做乘除法有什么意义..



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值