ptrdiff_t可以代表指向同一数组对象的元素的所有指针减法吗? [英] Can ptrdiff_t represent all subtractions of pointers to elements of the same array object?

查看:101
本文介绍了ptrdiff_t可以代表指向同一数组对象的元素的所有指针减法吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用于将指针ij减去相同数组对象的元素 [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):

  1. 类型ptrdiff_­t是由实现定义的带符号整数类型,它可以容纳一个数组对象中两个下标的差,如
  1. 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 of ptrdiff_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.

首先,请注意,不考虑ij是不同数组的下标索引的情况.这允许将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

如果表达式PQ分别指向同一数组对象x的元素x[i]x[j],则表达式P - Q的值为i−j ; 否则,行为是不确定的.

[expr.add]/5

If the expressions P and Q point to, respectively, elements x[i] and x[j] of the same array object x, the expression P - Q has the value i−j ; otherwise, the behavior is undefined.

结论是,使用前面定义的符号,i-jP-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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆