size_t 与 uintptr_t [英] size_t vs. uintptr_t
问题描述
C 标准保证 size_t
是一种可以保存任何数组索引的类型.这意味着,从逻辑上讲,size_t
应该能够保存任何指针类型.我在 Google 上发现的一些网站上读到,这是合法的和/或应该始终有效:
The C standard guarantees that size_t
is a type that can hold any array index. This means that, logically, size_t
should be able to hold any pointer type. I've read on some sites that I found on the Googles that this is legal and/or should always work:
void *v = malloc(10);
size_t s = (size_t) v;
然后在 C99 中,标准引入了 intptr_t
和 uintptr_t
类型,它们是保证能够保存指针的有符号和无符号类型:
So then in C99, the standard introduced the intptr_t
and uintptr_t
types, which are signed and unsigned types guaranteed to be able to hold pointers:
uintptr_t p = (size_t) v;
那么使用 size_t
和 uintptr_t
有什么区别?两者都是无符号的,并且都应该能够保存任何指针类型,因此它们在功能上看起来是相同的.除了清晰度之外,是否有任何真正令人信服的理由使用 uintptr_t
(或者更好的是,void *
)而不是 size_t
?在不透明的结构中,该字段仅由内部函数处理,是否有任何理由不这样做?
So what is the difference between using size_t
and uintptr_t
? Both are unsigned, and both should be able to hold any pointer type, so they seem functionally identical. Is there any real compelling reason to use uintptr_t
(or better yet, a void *
) rather than a size_t
, other than clarity? In an opaque structure, where the field will be handled only by internal functions, is there any reason not to do this?
同理,ptrdiff_t
已经是一个能够保存指针差异的有符号类型,因此能够保存几乎任何指针,那么它与 intptr_t
有什么区别?
By the same token, ptrdiff_t
has been a signed type capable of holding pointer differences, and therefore capable of holding most any pointer, so how is it distinct from intptr_t
?
不是所有这些类型基本上都服务于相同功能的微不足道的不同版本吗?如果不是,为什么?我不能用其中一个做什么而我不能用另一个?如果是这样,为什么 C99 会在语言中添加两个本质上是多余的类型?
Aren't all of these types basically serving trivially different versions of the same function? If not, why? What can't I do with one of them that I can't do with another? If so, why did C99 add two essentially superfluous types to the language?
我愿意忽略函数指针,因为它们不适用于当前的问题,但请随意提及它们,因为我偷偷怀疑它们将成为正确"答案的核心.
I'm willing to disregard function pointers, as they don't apply to the current problem, but feel free to mention them, as I have a sneaking suspicion they will be central to the "correct" answer.
推荐答案
size_t
是一种可以保存任何数组索引的类型.这意味着,从逻辑上讲, size_t 应该能够持有任何指针类型
size_t
is a type that can hold any array index. This means that, logically, size_t should be able to hold any pointer type
不一定!回到分段 16 位架构的时代,例如:一个数组可能仅限于单个段(因此 16 位 size_t
可以)但您可以有多个段(因此 32-bit intptr_t
类型将需要选择段以及其中的偏移量).我知道在这些可统一寻址的非分段架构的日子里,这些事情听起来很奇怪,但标准必须满足比2009 年的正常情况"更广泛的需求,你知道!-)
Not necessarily! Hark back to the days of segmented 16-bit architectures for example: an array might be limited to a single segment (so a 16-bit size_t
would do) BUT you could have multiple segments (so a 32-bit intptr_t
type would be needed to pick the segment as well as the offset within it). I know these things sound weird in these days of uniformly addressable unsegmented architectures, but the standard MUST cater for a wider variety than "what's normal in 2009", you know!-)
这篇关于size_t 与 uintptr_t的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!