C++ intptr_t 有什么用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35071200/
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
What is the use of intptr_t?
提问by Baruch
I know it is an integer type that can be cast to/from pointer without loss of data, but why would I ever want to do this? What advantage does having an integer type have over void*
for holding the pointer and THE_REAL_TYPE*
for pointer arithmetic?
我知道它是一个整数类型,可以在不丢失数据的情况下转换为/从指针转换,但我为什么要这样做?void*
与持有指针和THE_REAL_TYPE*
指针算术相比,拥有整数类型有什么优势?
EDIT
The question marked as "already been asked" doesn't answer this. The question there is if using intptr_t
as a general replacment for void*
is a good idea, and the answers there seem to be "don't use intptr_t", so my question is still valid: What would be a good use case for intptr_t
?
编辑
标记为“已经被问过”的问题没有回答这个问题。问题是,如果将其intptr_t
用作一般替换void*
是一个好主意,那么答案似乎是“不要使用 intptr_t”,所以我的问题仍然有效:什么是好的用例intptr_t
?
采纳答案by Sourav Ghosh
The primary reason, you cannot do bitwise operation on a void *
, but you can do the same on a intptr_t
.
主要原因,您不能对 a 进行按位运算void *
,但您可以对 a 进行相同的操作intptr_t
。
On many occassion, where you need to perform bitwise operation on an address, you can use intptr_t
.
在许多情况下,您需要对地址执行按位运算,您可以使用intptr_t
.
However, for bitwise operations, best approach is to use the unsigned
counterpart, uintptr_t
.
但是,对于按位运算,最好的方法是使用unsigned
对应的uintptr_t
.
As mentioned in the other answerby @chux, pointer comparison is another important aspect.
如在所提到的其他的答案由@chux,指针比较是另一个重要方面。
Also, FWIW, as per C11
standard, §7.20.1.4,
此外,FWIW,根据C11
标准,§7.20.1.4,
These types are optional.
这些类型是可选的。
回答by Lightness Races in Orbit
There's also a semantic consideration.
还有一个语义考虑。
A void*
is supposed to point to something. Despite modern practicality, a pointer is not a memory address. Okay, it usually/probably/always(!) holds one, but it's not a number. It's a pointer. It refers to a thing.
Avoid*
应该指向某事。尽管现代实用,指针不是内存地址。好的,它通常/可能/总是(!)持有一个,但它不是一个数字。这是一个指针。它指的是一件事情。
A intptr_t
does not. It's an integer value, that is safe to convert to/from a pointer so you can use it for antique APIs, packing it into a pthread
function argument, things like that.
Aintptr_t
没有。它是一个整数值,可以安全地转换为/从指针转换,因此您可以将其用于古董 API,将其打包到pthread
函数参数中,诸如此类。
That's why you can do more numbery and bitty things on an intptr_t
than you can on a void*
, and why you should be self-documenting by using the proper type for the job.
这就是为什么你可以在 an 上做intptr_t
比在 a上做的更多和琐碎的事情void*
,以及为什么你应该通过使用正确的工作类型来进行自我记录。
Ultimately, almost everything couldbe an integer (remember, your computer works on numbers!). Pointers could have been integers. But they're not. They're pointers, because they are meant for different use. And, theoretically, they could be something other than numbers.
最终,几乎所有东西都可以是整数(请记住,您的计算机可以处理数字!)。指针可以是整数。但他们不是。它们是指针,因为它们的用途不同。而且,理论上,它们可能不是数字。
回答by chux - Reinstate Monica
What is the use of intptr_t?
intptr_t 有什么用?
Example use: order comparing.
Comparing pointers for equality is not a problem.
Other compare operations like >, <=
may be UB. C11dr §6.5.8/5 Relational operators.
So convert to intptr_t
first.
示例用途:订单比较。
比较指针是否相等不是问题。
其他比较操作>, <=
可能是 UB。C11dr §6.5.8/5 关系运算符。
所以转换为intptr_t
第一个。
[Edit] New example: Sort an array of pointers by pointer value.
[编辑] 新示例:按指针值对指针数组进行排序。
int ptr_cmp(const void *a, const void *b) {
intptr_t ia = (intptr) (*((void **) a));
intptr_t ib = (intptr) (*((void **) b));
return (ia > ib) - (ia < ib);
}
void *a[N];
...
qsort(a, sizeof a/sizeof a[0], sizeof a[0], ptr_cmp);
[Former example] Example use: Test if a pointer is of an array of pointers.
[前一个例子] 示例使用:测试一个指针是否是一个指针数组。
#define N 10
char special[N][1];
// UB as testing order of pointer, not of the same array, is UB.
int test_special1(char *candidate) {
return (candidate >= special[0]) && (candidate <= special[N-1]);
}
// OK - integer compare
int test_special2(char *candidate) {
intptr_t ca = (intptr_t) candidate;
intptr_t mn = (intptr_t) special[0];
intptr_t mx = (intptr_t) special[N-1];
return (ca >= mn) && (ca <= mx);
}
As commented by @M.M, the above code may not work as intended. But at least it is not UB. - just non-portably functionality. I was hoping to use this to solve this problem.
回答by Arlie Stephens
The uintptr_t type is very useful when writing memory management code. That kind of code wants to talk to its clients in terms of generic pointers (void *), but internally do all kinds of arithmetic on addresses.
uintptr_t 类型在编写内存管理代码时非常有用。那种代码想通过通用指针 (void *) 与它的客户交谈,但在内部对地址进行各种算术运算。
You can do some of the same things by operating in terms of char *, but not everything, and the result looks like pre-Ansi C.
你可以通过操作 char * 来做一些相同的事情,但不是所有的东西,结果看起来像 Ansi C 之前的样子。
Not all memory management code uses uintptr_t - as an example, the BSD kernel code defines a vm_offset_t with similar properties. But if you are writing e.g. a debug malloc package, why invent your own type?
并非所有内存管理代码都使用 uintptr_t - 例如,BSD 内核代码定义了一个具有类似属性的 vm_offset_t。但是如果你正在编写一个调试 malloc 包,为什么要发明你自己的类型?
It's also helpful when you have %p available in your printf, and are writing code that needs to print pointer sized integral variables in hex on a variety of architectures.
当您的 printf 中有 %p 可用并且正在编写需要在各种体系结构上以十六进制打印指针大小的整数变量的代码时,这也很有帮助。
I find intptr_t rather less useful, except possibly as a way station when casting, to avoid the dread warning about changing signedness and integer size in the same cast. (Writing portable code that passes -Wall -Werror on all relevant architectures can be a bit of a struggle.)
我发现 intptr_t 不太有用,除非可能作为转换时的中转站,以避免在同一转换中更改符号和整数大小的可怕警告。(在所有相关架构上编写通过 -Wall -Werror 的可移植代码可能有点困难。)