C++ 中的指针比较是未定义或未指定的行为吗?
Is pointer comparison undefined or unspecified behavior in C++?
Stroustrup 编写的 C++ 编程语言第 3 版说,
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
}
我在维基百科上读到 unspecified behavior。它说
在 C 和 C++ 中,仅当指针指向同一对象的成员或同一数组的元素时,才严格定义对象指针的比较。
示例:
int main(void)
{
int a = 0;
int b = 0;
return &a < &b; /* unspecified behavior in C++, undefined in C */
}
所以,我很困惑。哪一个是正确的?维基百科或 Stroustrup 的书? C++ 标准对此有何规定?
如果我误解了什么请纠正我。
注意指针减法和指针比较是不同的运算,规则不同
C++14 5.6/6,关于指针减法:
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:
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.
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.
Stroustrup 编写的 C++ 编程语言第 3 版说,
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
}
我在维基百科上读到 unspecified behavior。它说
在 C 和 C++ 中,仅当指针指向同一对象的成员或同一数组的元素时,才严格定义对象指针的比较。
示例:
int main(void)
{
int a = 0;
int b = 0;
return &a < &b; /* unspecified behavior in C++, undefined in C */
}
所以,我很困惑。哪一个是正确的?维基百科或 Stroustrup 的书? C++ 标准对此有何规定?
如果我误解了什么请纠正我。
注意指针减法和指针比较是不同的运算,规则不同
C++14 5.6/6,关于指针减法:
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:
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.
If two operands
p
andq
compare equal (5.10),p<=q
andp>=q
both yieldtrue
andp<q
andp>q
both yield false. Otherwise, if a pointerp
compares greater than a pointerq
,p>=q
,p>q
,q<=p
, andq<p
all yieldtrue
, andp<=q
,p<q
,q>=p
, andq>p
all yieldfalse
. Otherwise, the result of each of the operators is unspecified.