ptrdiff_不能表示指向同一数组对象元素的指针的所有减法吗?

对于将指针ij减去同一数组对象的元素,[expr.add#5]on 注释如下:

[ 注意:如果值i−j不在std类型的可表示值范围内​::​ptrdiff­t,行为未定义- 结束注释]

但是给出了[support.types.layout#2],其中指出(emphasismine):

  1. 类型ptrdiff\ut是一种实现定义的有符号整数类型,可以容纳数组对象中两个下标的差值,如[expr.add]on所述

i-j的结果是否可能不在ptrdiff\u t的可表示值范围内

附言:如果我的问题是由于我对英语理解不好引起的,我道歉

编辑:相关:为什么数组的最大大小是"太大了

i-j的结果是否可能不在ptrdiff\u t的可表示值范围内

是的,但不太可能

事实上,[support.types.layout]/2除了在[expr.add]中定义了有关指针减法和ptrdiff\t的适当规则外,没有太多说明。让我们看看这一节

[expr.add]/5

当减去指向同一数组对象的元素的两个指针时,结果的类型是实现定义的有符号整数类型;该类型应与定义为std的类型相同​::​中的ptrdiff\ut<cstdef&gt标题

首先,注意不考虑ij是不同数组的下标索引的情况。这允许将i-j视为P-Q,其中P是指向下标i处数组元素的指针,Q是指向下标j处相同数组元素的指针。实际上,减去指向不同数组元素的两个指针是未定义的行为:

[expr.add]/5

如果表达式pQ分别指向同一数组对象x的元素x[i]x[j],则表达式p-Q的值为i−j
; 否则,行为未定义

作为结论,使用前面定义的符号,i-jp-Q被定义为具有相同的值,后者的类型为std::ptrdiff_t。但是,对于这种类型持有这样一个值的可能性,我们却只字未提。然而,这个问题可以借助于std::numeric_limits;特别是,可以检测数组some_array是否太大std::ptrdiff_t无法容纳所有索引差异:

静态断言(std::numeric\u limits<std::ptrdiff\u t>::max()>sizeof(某些数组)/sizeof(某些数组[0]),
某些_数组太大,将其第一个和结束元素索引后的一个相减
“或指针将导致未定义的行为,如[expr.add]/5。”
);

现在,在通常的目标上,这通常不会发生,因为sizeof(std::ptrdiff_t)==sizeof(void*);这意味着数组需要非常大才能溢出ptrdiff\u t。但这并不能保证

发表评论