什么是uintptr_t数据类型

时间:2009-12-04 07:52:12

标签: c++ pointers types

什么是uintptr_t以及它可以用于什么?

5 个答案:

答案 0 :(得分:219)

首先,在提出问题时,uintptr_t不在C ++中。它位于<stdint.h>的C99中,作为可选类型。许多C ++ 03编译器都提供该文件。它也在C ++ 11中,在<cstdint>中,同样它也是可选的,它引用了C99作为定义。

在C99中,它被定义为“无符号整数类型,其属性是任何有效的指向void的指针都可以转换为此类型,然后转换回指向void的指针,结果将等于原始指针”

这意味着它的意思。它没有说明大小。

uintptr_t可能与void*的大小相同。它可能更大。可以想象它可以更小,尽管这样的C ++实现方法有悖常理。例如,在void*为32位但只使用24位虚拟地址空间的某个假设平台上,您可以使用满足要求的24位uintptr_t。我不知道为什么一个实现会这样做,但标准允许它。

答案 1 :(得分:170)

uintptr_t是一种无符号整数类型,能够存储指针。这通常意味着它与指针的大小相同。

It is optionally defined in C++11 and later standards.

想要一个可以保存体系结构指针类型的整数类型的一个常见原因是对指针执行特定于整数的操作,或者通过将指针提供为整数“句柄”来模糊指针的类型。

编辑:请注意,史蒂夫杰索普有一些非常有趣的额外细节(我不会偷窃)in another answer here为你迂腐的类型:)

答案 2 :(得分:18)

这是一个无符号整数类型,与指针的大小完全相同。每当你需要用指针做一些不寻常的事情时 - 例如反转所有位(不要问为什么)你将它转换为uintptr_t并将其作为通常的整数进行操作,然后再回滚。

答案 3 :(得分:8)

该部分已经有很多好的答案&#34;什么是uintptr_t数据类型&#34;。我将尝试解决&#34;它可以用于什么?&#34;参与这篇文章。

主要用于指针的按位操作。请记住,在C ++中,无法对指针执行按位操作。有理由,请参阅Why can't you do bitwise operations on pointer in C, and is there a way around this?

因此,为了对指针执行按位操作,需要将指针转换为类型unitpr_t,然后执行按位运算。

这是一个函数的例子,我刚刚编写为按位排序或2个指针存储在XOR链表中,这样我们就可以像双向链表那样在两个方向上遍历,但不会存储2个指针在每个节点中。

 template <typename T>
 T* xor_ptrs(T* t1, T* t2)
 {
     return reinterpret_cast<T*>(reinterpret_cast<uintptr_t>(t1)^reinterpret_cast<uintptr_t>(t2));
  }

答案 4 :(得分:1)

冒着获得另一个死灵法师徽章的风险,我想为uintptr_t(甚至是intptr_t)添加一个很好的用法,那就是编写可测试的嵌入式代码。 我主要针对各种手臂和当前的tensilica处理器编写嵌入式代码。它们具有各种本机总线宽度,而tensilica实际上是哈佛架构,具有可以不同宽度的单独的代码和数据总线。我对大多数代码使用测试驱动的开发风格,这意味着我对所编写的所有代码单元都进行了单元测试。在实际目标硬件上进行单元测试很麻烦,因此我通常使用Ceedling和GCC在Windows或Linux的基于Intel的PC上编写所有内容。话虽这么说,许多嵌入式代码都涉及位纠缠和地址操纵。我的大多数Intel机器都是64位的。因此,如果要测试地址操作代码,则需要一个通用对象来进行数学运算。因此,在尝试部署到目标硬件之前,uintptr_t提供了一种与机器无关的调试代码的方式。 对于某些机器,甚至某些编译器上的内存模型,另一个问题是函数指针和数据指针的宽度不同。在这些机器上,编译器甚至可能不允许在这两个类之间进行强制转换,但是uintptr_t应该能够保留其中任何一个。