Ste*_*sop 225
首先,在提出问题的时候,问题uintptr_t不在于C++.它在C99中<stdint.h>,作为可选类型.许多C++ 03编译器都提供该文件.它也在C++ 11中,在<cstdint>那里它也是可选的,它引用了C99的定义.
在C99中,它被定义为"无符号整数类型,其属性是任何有效的指向void的指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较".
这意味着它的意思.它没有说明大小.
uintptr_t可能与a的大小相同void*.它可能更大.可以想象它可以更小,尽管这样的C++实现有些不正常.例如,在一些void*32位的假设平台上,但只使用了24位的虚拟地址空间,您可以使用uintptr_t满足要求的24位.我不知道为什么一个实现会这样做,但标准允许它.
Dre*_*ann 181
uintptr_t是无符号整数类型,能够存储指针.这通常意味着它与指针的大小相同.
想要一个可以保存体系结构指针类型的整数类型的一个常见原因是对指针执行整数特定的操作,或者通过将指针提供为整数"句柄"来模糊指针的类型.
编辑:请注意,史蒂夫杰索普有一些非常有趣的额外细节(我不会偷)在另一个答案在这里为你迂腐的类型:)
sha*_*oth 19
它是一个无符号整数类型,与指针的大小完全相同.每当你需要用指针做一些不寻常的事情时 - 例如反转所有位(不要问为什么)你将它转换为uintptr_t并将其作为通常的整数进行操作,然后再回滚.
BGR*_*BGR 12
"什么是uintptr_t数据类型"部分已经有很多很好的答案.我会尝试解决"它可以用于什么?" 这篇文章的一部分.
主要用于指针的按位操作.请记住,在C++中,无法对指针执行按位操作.由于原因,请参阅为什么不能对C中的指针进行按位操作,有没有办法解决这个问题?
因此,为了对指针进行按位操作,需要将指针转换为类型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));
}
Run Code Online (Sandbox Code Playgroud)
冒着获得另一个死灵法师徽章的风险,我想为uintptr_t(甚至intptr_t)添加一个非常好的用途,那就是编写可测试的嵌入式代码。
我主要编写针对各种 arm 和当前 tensilica 处理器的嵌入式代码。它们具有不同的原生总线宽度,并且 Tensilica 实际上是一种哈佛架构,具有不同宽度的单独代码和数据总线。
我对我的大部分代码使用测试驱动的开发风格,这意味着我对我编写的所有代码单元进行单元测试。在实际目标硬件上进行单元测试很麻烦,因此我通常使用 Ceedling 和 GCC 在 Windows 或 Linux 中的基于 Intel 的 PC 上编写所有内容。
话虽如此,许多嵌入式代码都涉及位处理和地址操作。我的大部分 Intel 机器都是 64 位的。因此,如果您要测试地址操作代码,则需要一个通用对象来进行数学运算。因此,uintptr_t在您尝试部署到目标硬件之前,它为您提供了一种独立于机器的调试代码的方式。
另一个问题是对于某些机器甚至某些编译器上的内存模型,函数指针和数据指针的宽度不同。在这些机器上,编译器甚至可能不允许在两个类之间进行转换,但uintptr_t应该能够保持。
- 编辑 -
@chux 指出,这不是标准的一部分,函数也不是 C 中的对象。但是它通常可以工作,而且由于很多人甚至不知道这些类型,我通常会发表评论来解释这个技巧。SO on 中的其他搜索uintptr_t将提供进一步的解释。我们还在单元测试中做一些我们在生产中永远不会做的事情,因为打破东西是好的。