Pointers to one end and end of an object

I know that comparison of pointers is only determined if two pointers point somewhere in the storage allocated for the same object, or if they are NULL or one end of the object if it is not dereferenced.

I use "object" in the standard sense of "C".

Is there any special dispensation for comparing two pointers that are as follows: one after the end of an object, as opposed to comparing a pointer with one end and the resulting pointer expression referring to the actual object. Given the following definitions:

char arr[100]; char *pend = &arr[99]; char *pa = pend+1; char *pb = pend+1; 

is a comparison pa == pb guaranteed value, or does it call UB because -ne-pa or pb points to arr.

In other words, from a standard point of view, is there a semantic difference between comparing pa and pb and comparing, say, pa and &arr[99]+1 ? this may seem obvious, but :)

+6
source share
2 answers

This is a good example of why you should not mark your questions in both C and C ++:

For C, this is covered by the standard.

6.5.9 Equality Operators

6 Two pointers compare the same if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at the beginning) or a function, both are pointers to the same past, the last element of the same object array , or one is a pointer to one end of the end of one array object, and the other is a pointer to the beginning of another array object, which occurs immediately after the first array object in the address space.

For C ++, this is not so clear:

5.10 Equality Operators [expr.eq]

1 == (equal) and != (Not equal) operators have the same semantic restrictions, transformations, and result type as relational operators, except for their lower priority and true result. [Note: a<b == c<d is true when a<b and c<d have the same truth value. - end note] Pointers of the same type (after pointer conversions) can be compared for equality. Two pointers of the same type are compared equally if and only if both are equal to zero, both indicate the same function, or both represent the same address (3.9.2) .

Technically, I don’t see where the standard requires that two pointers of the past end represent the same address. I can find where the standard requires the object to have an address, and the & operator returns that specific address (so that with a double address address the same pointer value is obtained), but the past end pointer does not point to the object, so this does not apply . They can be different, while subtraction works to return to the same array base.

In practice, however, you will not have to worry about this, and it will work in C ++ in the same way as in C.

Update: to JohnB's answer and comments there, the C ++ standard may have required this much more explicitly, but it does require indirectly nonetheless.

+6
source

In C ++, which is guaranteed only for forward iterators:

24.2.5 forward iterators

A class or pointer type X satisfies the requirements of an advanced iterator if [...] type X objects offer a multi-pass guarantee, described below. [...]

Domain == for forward iterators - these are iterators over the same main sequence. [...]

Two dereferenced iterators a and b of type X offer multi-pass if:

- a == b implies ++ a == ++ b and [...]

From 24.4.1 (the iterator_traits specialization for pointers) it follows that pointers are random access iterators and thus forward iterators.

Alternatively, but perhaps less convincingly, for arrays, you can implicitly conclude that (p+1) == (q+1) , if both p and q point to the last element of the array, from the wording of the following:

5.7 Additive operators [...] Moreover, if the expression P indicates the last element of the array object, the expression (P) +1 indicates one after the last element of the array, and if the expression Q indicates one after the last element of the array object, the expression (Q) -1 indicates the last element of an array object.

This implies that there is one clearly defined address representing "one after the last element". (Arrays are linear, "one after the last element" includes the fiction that the linear array of objects is expanded, and the natural extension of the linear thing is linear again, so there can only be one: "past the last element Note the difference that the standard makes between" one past past last element and just past the last element elsewhere.)

+2
source

Source: https://habr.com/ru/post/972565/


All Articles