size_t ptrdiff_t 和地址 space

size_t ptrdiff_t and address space

在我的系统上 ptrdiff_tsize_t 都是 64 位.

我想澄清两件事:

不,没有这样的保证。例如,参见此处:https://en.cppreference.com/w/cpp/types/ptrdiff_t

If an array is so large (greater than PTRDIFF_MAX elements, but less than SIZE_MAX bytes), that the difference between two pointers may not be representable as std::ptrdiff_t, the result of subtracting two such pointers is undefined.

大多数实现人为地限制了最大数组大小,以确保指向同一数组的两个指针之间的差异适合 ptrdiff_t。因此,在您的平台上,允许的最大数组大小很可能约为 SIZE_MAX / 2(尝试一下)。这不是 "address space restriction",它只是您的实施在内部强制执行的限制。在此限制下,合法的指针减法("legal" = 两个指针指向同一个数组)不会溢出。

虽然语言规范没有要求。实现不需要以这种方式限制它们的数组大小,这意味着语言规范允许看似合法的指针减法溢出并产生未定义的行为。但是大多数实现更喜欢通过限制数组大小来防御这种情况。

请参阅此处的 "three options" 了解更多详情:

来自 [support.types.layout]/3

The type size_t is an implementation-defined unsigned integer type that is large enough to contain the size in bytes of any object.

所以你保证 size_t 可以容纳你可以拥有的最大数组的大小。

ptrdiff_t 不幸的是不能保证。来自 [support.types.layout]/2

The type ptrdiff_t is an implementation-defined signed integer type that can hold the difference of two subscripts in an array object, as described in 8.7.

还可以,但是我们有 [expr.add]/5

When two pointers to elements of the same array object are subtracted, the type of the result is an implementation-defined signed integral type; this type shall be the same type that is defined as std::ptrdiff_t in the header (21.2). If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i − j; otherwise, the behavior is undefined. [ Note: If the value i − j is not in the range of representable values of type std::ptrdiff_t, the behavior is undefined. —end note ]

其中指出 ptrdiff_t 可能不够大。