One-past-end-of-object pointers

O

ozbear

This is probably an obvious question.

I know that pointer comparisons are only defined if the two pointers
point somewhere "into" the storage allocated to the same object, or if
they are NULL, or one-past the end of the object as long as it isn't
dereferenced.

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

Is there some special dispensation given to comparing two pointers
that are -each- one past the end of the object as opposed to
comparing a one-past-end pointer and an pointer expression derived
referencing the actual object. Given the following definitions:

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

is the comparison pa == pb guaranteed to be meaningful or does it
invoke UB because -neither- pa nor pb point into arr.

In otherwords, from the standard's point of view, is there a
semantic difference between comparing pa and pb and comparing,
say, pa and &arr[99]+1 ?

Oz
 
B

Ben Pfaff

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

is the comparison pa == pb guaranteed to be meaningful or does it
invoke UB because -neither- pa nor pb point into arr.

It is meaningful. pa and pb will compare equal. See 6.5.9#6:

Two pointers compare equal 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 its beginning) or
function, both are pointers to one past the last element of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the same array object, or one is a pointer to one past the
^^^^^^^^^^^^^^^^^^^^^
end of one array object and the other is a pointer to the
start of a different array object that happens to
immediately follow the first array object in the address
space.91)

(Note the final clause, which could cause a "false equal"
condition if the pointers point into different objects.)
 
M

Mike Wahler

ozbear said:
This is probably an obvious question.

I know that pointer comparisons are only defined if the two pointers
point somewhere "into" the storage allocated to the same object, or if
they are NULL, or one-past the end of the object as long as it isn't
dereferenced.

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

Is there some special dispensation given to comparing two pointers
that are -each- one past the end of the object as opposed to
comparing a one-past-end pointer and an pointer expression derived
referencing the actual object. Given the following definitions:

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

is the comparison pa == pb guaranteed to be meaningful or does it
invoke UB because -neither- pa nor pb point into arr.

In otherwords, from the standard's point of view, is there a
semantic difference between comparing pa and pb and comparing,
say, pa and &arr[99]+1 ?

====================== begin quote ====================================
ISO/IEC 9899:1999 (E)

[....]

6.5.8 Relational operators

[....]

5 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 or incomplete types both point to the same object,
or both point one past the last element of the same array object,
they compare equal. If the objects pointed to are members of the same
aggregate object, pointers to structure members declared later compare
greater than pointers to members declared earlier in the structure,
and pointers to array elements with larger subscript values compare
greater than pointers to elements of the same array with lower subscript
values. All pointers to members of the same union object compare equal.
If the expression P points to an element of an array object and the
expression Q points to the last element of the same array object, the
pointer expression Q+1 compares greater than P. In all other cases, the
behavior is undefined.

[....]

6.5.9 Equality operators

[....]

6 Two pointers compare equal 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 its beginning) or function, both are pointers to one past
the last element of the same array object, or one is a pointer to one
past the end of one array object and the other is a pointer to the start
of a different array object that happens to immediately follow the first
array object in the address space.(91)

[....]

(91) Two objects may be adjacent in memory because they are adjacent
elements of a larger array or adjacent members of a structure with
no padding between them, or because the implementation chose to
place them so, even though they are unrelated. If prior invalid
pointer operations (such as accesses outside array bounds) produced
undefined behavior, subsequent comparisons also produce undefined
behavior.
====================== end quote ====================================

-Mike
 
P

pete

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

is the comparison pa == pb guaranteed to be meaningful or does it
invoke UB because -neither- pa nor pb point into arr.

It is meaningful. pa and pb will compare equal. See 6.5.9#6:

Two pointers compare equal 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 its beginning) or
function, both are pointers to one past the last element of
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
the same array object, or one is a pointer to one past the
^^^^^^^^^^^^^^^^^^^^^
end of one array object and the other is a pointer to the
start of a different array object that happens to
immediately follow the first array object in the address
space.91)

(Note the final clause, which could cause a "false equal"
condition if the pointers point into different objects.)

That's not a false equal.
If two objects are contigous in memory, then
the one past pointer from the first object,
really is equal to the start of the next object,
(and a single string could span both objects).
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top