结果是否甚至可能i-j不在 的可表示值范围内ptrdiff_t?
是的,但不太可能。
事实上,[support.types.layout]/2除了关于指针减法的正确规则并ptrdiff_t在[expr.add]. 那么让我们看看这个部分。
当两个指向同一个数组对象的元素的指针相减时,结果的类型是实现定义的有符号整数类型;此类型应与标题中定义的类型std::ptrdiff_t相同<cstddef>。
首先,请注意,不考虑i和j是不同数组的下标索引的情况。这允许将 wherei-j视为指向下标数组元素的指针,并且是指向下标相同数组元素的指针。实际上,减去两个指向不同数组元素的指针是未定义的行为:P-QPiQj
如果表达式P和Q分别指向同一数组对象的元素x[i]和,则表达式具有值
;否则,行为是 undefined。x[j]xP - Qi−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才能溢出。但不能保证。