Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is pointer comparison undefined or unspecified behavior in C++?

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.

For example:

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

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.

Example:

int main(void)
{
  int a = 0;
  int b = 0;
  return &a < &b; /* unspecified behavior in C++, undefined in 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.

like image 905
Destructor Avatar asked Aug 02 '15 17:08

Destructor


People also ask

What type of behavior C is undefined?

According to the C standards, signed integer overflow is undefined behaviour too. A few compilers may trap the overflow condition when compiled with some trap handling options, while a few compilers simply ignore the overflow conditions (assuming that the overflow will never happen) and generate the code accordingly.

Can pointers be compared in C?

How to compare pointers in C/C++? We can compare pointers if they are pointing to the same array. Relational pointers can be used to compare two pointers. Pointers can't be multiplied or divided.

Is pointer arithmetic undefined behavior?

That's because pointers don't behave like integers. It's undefined behavior because the standard says so. On most platforms however (if not all), you won't get a crash or run into dubious behavior if you don't dereference the array.

Can you compare pointers of different types?

When two pointers are compared, the result depends on the relative locations in the address space of the objects pointed to. If two pointers to object types both point to the same object, or both point one past the last element of the same array object, they compare equal.


1 Answers

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

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:

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.

like image 173
aschepler Avatar answered Oct 01 '22 03:10

aschepler