结果是否甚至可能i-j
不在 的可表示值范围内ptrdiff_t
?
是的,但不太可能。
事实上,[support.types.layout]/2
除了关于指针减法的正确规则并ptrdiff_t
在[expr.add]
. 那么让我们看看这个部分。
当两个指向同一个数组对象的元素的指针相减时,结果的类型是实现定义的有符号整数类型;此类型应与标题中定义的类型std::ptrdiff_t
相同<cstddef>
。
首先,请注意,不考虑i
和j
是不同数组的下标索引的情况。这允许将 wherei-j
视为指向下标数组元素的指针,并且是指向下标相同数组元素的指针。实际上,减去两个指向不同数组元素的指针是未定义的行为:P-Q
P
i
Q
j
如果表达式P
和Q
分别指向同一数组对象的元素x[i]
和,则表达式具有值
;否则,行为是 undefined。x[j]
x
P - Q
i−j
作为结论,使用前面定义的符号,i-j
和P-Q
被定义为具有相同的值,而后者的类型为std::ptrdiff_t
。但是对于这种类型是否有可能持有这样的值,没有任何说法。然而,这个问题可以在 ; 的帮助下回答std::numeric_limits
。特别是,可以检测一个数组some_array
是否太大而std::ptrdiff_t
无法容纳所有索引差异:
static_assert(std::numeric_limits<std::ptrdiff_t>::max() > sizeof(some_array)/sizeof(some_array[0]),
"some_array is too big, subtracting its first and one-past-the-end element indexes "
"or pointers would lead to undefined behavior as per [expr.add]/5."
);
现在,在通常的目标上,这通常不会发生为sizeof(std::ptrdiff_t) == sizeof(void*)
; 这意味着一个数组需要非常大ptrdiff_t
才能溢出。但不能保证。