对于将指针i
和j
减去同一数组对象的元素,[expr.add#5]on 注释如下:
[ 注意:如果值i−j不在
std类型的可表示值范围内::ptrdifft
,行为未定义- 结束注释]
但是给出了[support.types.layout#2],其中指出(emphasismine):
- 类型
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>标题
首先,注意不考虑i
和j
是不同数组的下标索引的情况。这允许将i-j
视为P-Q
,其中P
是指向下标i
处数组元素的指针,Q
是指向下标j
处相同数组元素的指针。实际上,减去指向不同数组元素的两个指针是未定义的行为:
[expr.add]/5
如果表达式
p
和Q
分别指向同一数组对象x
的元素x[i]
和x[j]
,则表达式p-Q
的值为i−j
; 否则,行为未定义
作为结论,使用前面定义的符号,i-j
和p-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
。但这并不能保证