C++ 什么是 uintptr_t 数据类型

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1845482/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 21:22:25  来源:igfitidea点击:

What is uintptr_t data type

c++pointerstypes

提问by dimba

What is uintptr_tand what can it be used for?

uintptr_t它是什么以及它可以用来做什么?

采纳答案by Drew Dormann

uintptr_tis an unsigned integer type that is capable of storing a data pointer. Which typically means that it's the same size as a pointer.

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

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

它在 C++11 和更高版本的标准中可选地定义。

A common reason to want an integer type that can hold an architecture's pointer type is to perform integer-specific operations on a pointer, or to obscure the type of a pointer by providing it as an integer "handle".

需要一个可以保存架构指针类型的整数类型的一个常见原因是对指针执行整数特定的操作,或者通过将指针的类型提供为整数“句柄”来隐藏指针的类型。

Edit: Note that Steve Jessop has some very interesting additional details (that I won't steal) in another answer herefor you pedantic types :)

编辑:请注意,Steve Jessop在另一个回答中为您提供了一些非常有趣的附加细节(我不会窃取):)

回答by Steve Jessop

First thing, at the time the question was asked, uintptr_twas not in C++. It's in C99, in <stdint.h>, as an optional type. Many C++03 compilers do provide that file. It's also in C++11, in <cstdint>, where again it is optional, and which refers to C99 for the definition.

第一件事,在问这个问题的时候,uintptr_t不是在 C++ 中。它在 C99 中,在<stdint.h>,作为可选类型。许多 C++03 编译器确实提供了该文件。它也在 C++11 中,在 中<cstdint>,它也是可选的,它指的是 C99 的定义。

In C99, it is defined as "an unsigned integer type with the property that any valid pointer to void can be converted to this type, then converted back to pointer to void, and the result will compare equal to the original pointer".

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

Take this to mean what it says. It doesn't say anything about size.

把这当作它所说的意思。它没有说明大小。

uintptr_tmight be the same size as a void*. It might be larger. It could conceivably be smaller, although such a C++ implementation approaches perverse. For example on some hypothetical platform where void*is 32 bits, but only 24 bits of virtual address space are used, you could have a 24-bit uintptr_twhich satisfies the requirement. I don't know why an implementation would do that, but the standard permits it.

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

回答by sharptooth

It's an unsigned integer type exactly the size of a pointer. Whenever you need to do something unusual with a pointer - like for example invert all bits (don't ask why) you cast it to uintptr_tand manipulate it as a usual integer number, then cast back.

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

回答by BGR

There are already many good answers to the part "what is uintptr_t data type". I will try to address the "what it can be used for?" part in this post.

“什么是uintptr_t数据类型”部分已经有很多很好的答案。我将尝试解决“它可以用来做什么?” 参与这篇文章。

Primarily for bitwise operations on pointers. Remember that in C++ one cannot perform bitwise operations on pointers. For reasons see Why can't you do bitwise operations on pointer in C, and is there a way around this?

主要用于指针的按位运算。请记住,在 C++ 中,不能对指针执行按位运算。原因参见为什么不能对 C 中的指针进行按位运算,有没有办法解决这个问题?

Thus in order to do bitwise operations on pointers one would need to cast pointers to type unitpr_t and then perform bitwise operations.

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

Here is an example of a function that I just wrote to do bitwise exclusive or of 2 pointers to store in a XOR linked list so that we can traverse in both directions like a doubly linked list but without the penalty of storing 2 pointers in each node.

这是我刚刚编写的一个函数示例,用于按位异或将 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));
  }

回答by bd2357

Running the risk of getting another Necromancer badge, I would like to add one very good use for uintptr_t (or even intptr_t) and that is writing testable embedded code. I write mostly embedded code targeted at various arm and currently tensilica processors. These have various native bus width and the tensilica is actually a Harvard architecture with separate code and data buses that can be different widths. I use a test driven development style for much of my code which means I do unit tests for all the code units I write. Unit testing on actual target hardware is a hassle so I typically write everything on an Intel based PC either in Windows or Linux using Ceedling and GCC. That being said, a lot of embedded code involves bit twiddling and address manipulations. Most of my Intel machines are 64 bit. So if you are going to test address manipulation code you need a generalized object to do math on. Thus the uintptr_t give you a machine independent way of debugging your code before you try deploying to target hardware. Another issue is for the some machines or even memory models on some compilers, function pointers and data pointers are different widths. On those machines the compiler may not even allow casting between the two classes, but uintptr_t should be able to hold either.

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