ptrdiff_t可以代表指向同一数组对象的元素的所有指针减法吗? [英] Can ptrdiff_t represent all subtractions of pointers to elements of the same array object?
问题描述
用于将指针i
和j
减去相同数组对象的元素 [expr.add#5] 中的注释为:
For subtraction of pointers i
and j
to elements of the same array object the note in [expr.add#5] reads:
[注意::如果值 ijj 不在类型为
std::ptrdiff_t
的可表示值的范围内,则行为是不确定的. — 尾注]
[ 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 ]
但是给定 [support.types.layout#2] ,其中指出(强调是我的):
But given [support.types.layout#2], which states that (emphasis mine):
- 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 [expr.add].
i-j
的结果是否甚至可能不在ptrdiff_t
的可表示值范围内?
Is it even possible for the result of i-j
not to be in the range of representable values of ptrdiff_t
?
PS:如果我的问题是由于我对英语的理解不足引起的,我深表歉意.
PS: I apologize if my question is caused by my poor understanding of the English language.
相关信息:为什么数组的最大大小太大"?
推荐答案
i-j
的结果是否甚至可能不在ptrdiff_t
的可表示值范围内?
Is it even possible for the result of
i-j
not to be in the range of representable values ofptrdiff_t
?
是的,但是不太可能.
实际上,除了在[expr.add]
中定义了有关指针减法和ptrdiff_t
的正确规则外,[support.types.layout]/2
并没有说太多.因此,让我们看看本节.
In fact, [support.types.layout]/2
does not say much except the proper rules about pointers subtraction and ptrdiff_t
are defined in [expr.add]
. So let us see this section.
[expr.add]/5
当减去指向同一数组对象元素的两个指针时,结果的类型为实现定义的带符号整数类型;此类型应与在
<cstddef>
标头中定义为std::ptrdiff_t
的类型相同.
[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<cstddef>
header.
首先,请注意,不考虑i
和j
是不同数组的下标索引的情况.这允许将i-j
视为P-Q
,其中P
是指向下标i
处的数组元素的指针,而Q
是指向相同元素的指针下标j
处的数组.实际上,减去两个指向不同数组元素的指针是未定义行为:
First of all, note that the case where i
and j
are subscript indexes of different arrays is not considered. This allows to treat i-j
as P-Q
would be where P
is a pointer to the element of an array at subscript i
and Q
is a pointer to the element of the same array at subscript j
. In deed, subtracting two pointers to elements of different arrays is undefined behavior:
[expr.add]/5
如果表达式
P
和Q
分别指向同一数组对象x
的元素x[i]
和x[j]
,则表达式P - Q
的值为i−j
; 否则,行为是不确定的.
[expr.add]/5
If the expressions
P
andQ
point to, respectively, elementsx[i]
andx[j]
of the same array objectx
, the expressionP - Q
has the valuei−j
; otherwise, the behavior is undefined.
结论是,使用前面定义的符号,i-j
和P-Q
被定义为具有相同的值,而后者的类型为 std::numeric_limits
的帮助下回答该问题.尤其是,可以检测到数组some_array
是否太大 ,而std::ptrdiff_t
不能容纳所有索引差:
As a conclusion, with the notation defined previously, i-j
and P-Q
are defined to have the same value, with the latter being of type std::ptrdiff_t
. But nothing is said about the possibility for this type to hold such a value. This question can, however, be answered with the help of std::numeric_limits
; especially, one can detect if an array some_array
is too big for std::ptrdiff_t
to hold all index differences:
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
要溢出,数组必须大得惊人.但是并不能保证.
Now, on usual target, this would usually not happen as sizeof(std::ptrdiff_t) == sizeof(void*)
; which means an array would need to be stupidly big for ptrdiff_t
to overflow. But there is no guarantee of it.
这篇关于ptrdiff_t可以代表指向同一数组对象的元素的所有指针减法吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!