C标准保证size_t
是一个可以保存任何数组下标的类型。这意味着,从逻辑上讲,size_t
应该能够保存任何指针类型。我在一些网站上读到,我在谷歌上发现这是合法的,并且/或应该总是有效的:
void *v = malloc(10);
size_t s = (size_t) v;
所以在C99中,标准引入了intptr_t
和uintptr_t
类型,它们是有符号和无符号类型,保证能够保存指针:
uintptr_t p = (size_t) v;
那么使用size_t
和uintptr_t
有什么区别呢?两者都是无符号的,并且都应该能够保存任何指针类型,因此它们在功能上似乎是相同的。除了清晰之外,使用uintptr_t
(或者更好的是void *
)而不是size_t
有什么真正令人信服的理由吗?在不透明结构中,字段将仅由内部函数处理,是否有理由不这样做?
出于同样的原因,ptrdiff_t
一直是一个能够保存指针差异的符号类型,因此能够保存几乎任何指针,那么它与intptr_t
有什么不同呢?
所有这些类型不都是服务于同一个函数的不同版本吗?如果不是,为什么?有什么是我用其中一个不能做而另一个不能做的?如果是这样,为什么C99要在语言中添加两个本质上多余的类型?
我愿意忽略函数指针,因为它们不适用于当前的问题,但可以随意提及它们,因为我怀疑它们将是“正确”答案的核心。