C++ 中的指针比较是未定义或未指定的行为吗?

Stroustrup 的 C++ 编程语言第 3 版说,

The C++ Programming Language 3rd edition by Stroustrup says that,

指针的减法只有在两个指针都指向时才定义同一个数组的元素(虽然语言没有快速的方法确保情况如此).当从另一个指针中减去一个指针时,结果是两个指针之间的数组元素数(一个整数).可以将一个整数加到一个指针上或减去一个来自指针的整数;在这两种情况下,结果都是一个指针值.如果该值不指向与原始指针或超出的指针,使用该值的结果是未定义.

Subtraction of pointers is defined only when both pointers point to elements of the same array (although the language has no fast way of ensuring that is the case). When subtracting one pointer from another, the result is the number of array elements between the two pointers (an integer). One can add an integer to a pointer or subtract an integer from a pointer; in both cases, the result is a pointer value. If that value does not point to an element of the same array as the original pointer or one beyond, the result of using that value is undefined.

例如:

void f ()
{
    int v1 [10];
    int v2 [10];
    int i1 = &v1[5] - &v1[3];   // i1 = 2
    int i2 = &v1[5] - &v2[3];   // result undefined
}

我在维基百科上阅读了关于未指明行为的内容.它说

I was reading about unspecified behavior on Wikipedia. It says that

在 C 和 C++ 中,只有当指针指向同一对象的成员或同一数组的元素时,才严格定义指向对象的指针的比较.

In C and C++, the comparison of pointers to objects is only strictly defined if the pointers point to members of the same object, or elements of the same array.

示例:

int main(void)
{
  int a = 0;
  int b = 0;
  return &a < &b; /* unspecified behavior in C++, undefined in C */
}

所以,我很困惑.哪一个是正确的?维基百科或 Stroustrup 的书?C++ 标准对此有何规定?

So, I am confused. Which one is correct? Wikipedia or Stroustrup's book? What C++ standard says about this?

如果我误解了什么,请纠正我.

Correct me If I am misunderstanding something.

推荐答案

注意,指针减法和指针比较是不同的操作,不同的规则.

Note that pointer subtraction and pointer comparison are different operations with different rules.

C++14 5.6/6,关于减指针:

C++14 5.6/6, on subtracting pointers:

除非两个指针都指向同一个数组对象的元素或指向数组对象最后一个元素之后的元素,否则行为未定义.

Unless both pointers point to elements of the same array object or one past the last element of the array object, the behavior is undefined.

C++14 5.9/3-4:

C++14 5.9/3-4:

比较指向对象的指针定义如下:

Comparing pointers to objects is defined as follows:

  • 如果两个指针指向同一数组的不同元素或其子对象,则指向下标较高的元素的指针比较大.

  • If two pointers point to different elements of the same array, or to subobjects thereof, the pointer to the element with the higher subscript compares greater.

如果一个指针指向数组的一个元素或其子对象,而另一个指针指向数组的最后一个元素,则后一个指针比较大.

If one pointer points to an element of an array, or to a subobject thereof, and another pointer points one past the last element of the array, the latter pointer compares greater.

如果两个指针递归地指向同一对象的不同非静态数据成员,或指向此类成员的子对象,则指向后声明成员的指针比较大,前提是这两个成员具有相同的访问控制和前提是他们的班级不是联合.

If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member compares greater provided the two members have the same access control and provided their class is not a union.

如果两个操作数 pq 比较相等(5.10),p<=qp>=q 都产生 truepp>q 都产生假.否则,如果指针 p 比较大于指针 qp>=qp>qq<=pq 都产生 truep<=q, pq>=pq>p 都会产生 false.否则,每个运算符的结果都是未指定的.

If two operands p and q compare equal (5.10), p<=q and p>=q both yield true and p<q and p>q both yield false. Otherwise, if a pointer p compares greater than a pointer q, p>=q, p>q, q<=p, and q<p all yield true, and p<=q, p<q, q>=p, and q>p all yield false. Otherwise, the result of each of the operators is unspecified.

相关文章