gpt4 book ai didi

c++ - 为什么 sizeof(ptrdiff_t) == sizeof(uintptr_t)

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:07:07 28 4
gpt4 key购买 nike

我看到几篇关于 size_t 与 uintptr_t/ptrdiff_t 的帖子(例如 size_t vs. uintptr_t),但没有关于这些新的 c99 ptr 大小类型的相对大小的帖子。

示例机器:vanilla ubuntu 14lts x64,gcc 4.8:

printf("%zu, %zu, %zu\n", sizeof(uintptr_t), sizeof(intptr_t), sizeof(ptrdiff_t));

打印:“8, 8, 8”

这对我来说没有意义,因为我希望必须签名的 diff 类型需要比 unsigned ptr 本身更多的位。

考虑:

NULL - (2^64-1)  /*largest ptr, 64bits of 1's.*/

2 的负补码不适合 64 位;因此我希望 ptrdiff_t 大于 ptr_t。

[一个相关的问题是为什么 intptr_t 与 uintptr_t 的大小相同......虽然我很舒服这可能只是为了允许带符号的类型包含表示的位(例如,在负 ptr 上使用带符号的算术会( a) 未定义,并且 (b) 实用性有限,因为 ptrs 根据定义是“正”)]

谢谢!

最佳答案

首先,很明显 uintptr_t 在这里做什么。语言(C 和 C++)不允许您从彼此中减去任何任意指针值。只有当两个指针指向同一个对象(指向同一个 array 对象)时,它们才能相减。否则,行为未定义。这意味着这两个指针之间的距离不可能超过 SIZE_MAX 字节。注意:距离受size_t范围限制,不受uintptr_t范围限制。在一般情况下,uintptr_t 可以是比 size_t 更大的类型。 C/C++ 中没有人向您保证您应该能够减去位于 UINTPTR_MAX 字节处的两个指针。

(是的,我知道在平面内存平台上 uintptr_tsize_t 通常是相同的类型,至少在范围和表示方面是这样。但是从语言的角度来看显然,假设它们始终如此是不正确的。)

您的NULL - (2^64-1)(如果解释为地址减法)就是这种有问题的减法的明显例子。是什么让您认为您应该首先能够做到这一点?

其次,从不相关的 uintptr_t 切换到更相关的 size_t 之后,可以说您的逻辑完全有效。 sizeof(ptrdiff_t) 应该大于 sizeof(size_t) 因为需要一个额外的位来表示签名结果。尽管如此,无论听起来多么奇怪,语言规范并不要求 ptrdiff_t 足够宽以容纳所有指针减法结果,即使两个指针指向同一对象的部分(即它们不超过SIZE_MAX 个字节)。 ptrdiff_t 在法律上被允许与 size_t 具有相同的位数。

这意味着“看似有效”的指针减法实际上可能仅仅因为结果太大而导致未定义的行为。如果您的实现允许您声明一个大小为 SIZE_MAX/3 * 2

char 数组
char array[SIZE_MAX / 3 * 2]; // This is smaller than `SIZE_MAX`

如果 ptrdiff_t 的大小与 size_t 相同,则减去指向该数组结尾和开头的完全有效的指针可能会导致未定义的行为

char *b = array;
char *e = array + sizeof array;

ptrdiff_t distance = e - b; // Undefined behavior!

这些语言的作者决定选择这种更简单的解决方案,而不是要求编译器实现对 [likely non-native] 超宽有符号整数类型 ptrdiff_t 的支持。

现实生活中的实现意识到了这个潜在的问题,并且通常会采取措施来避免它。他们人为地限制了最大支持对象的大小,以确保指针减法永远不会溢出。在典型的实现中,您将无法声明大于 PTRDIFF_MAX 字节(大约为 SIZE_MAX/2)的数组。例如。即使您平台上的 SIZE_MAX 为 264-1,该实现也不允许您声明任何大于 263-1 字节的内容(以及来自其他因素的现实生活限制可能比这更严格)。有了这个限制,任何合法的指针减法都会产生适合 ptrdiff_t 范围的结果。

另请参阅,

关于c++ - 为什么 sizeof(ptrdiff_t) == sizeof(uintptr_t),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30677435/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com