Reputation: 43
GCC compiler allows to use relational operators (such as ">", "<", ">=" and "<=") to compare pointers between them, but is it OK to do this, since we do not know in what order (towards higher or lower memory addresses) the stack grows?
For example, if we have an array of n integers and two ponters (*begin, that points to the first element (with index 0) and *end, that points to the n'th element (with index n-1)), will the (begin<=end) operation work properly in any case (for any design of the architecture)?
Upvotes: 4
Views: 142
Reputation: 223776
C 2024 6.5.9 specifies:
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.
Thus it is irrelevant how the array is actually laid out in the memory of the process, which direction the stack grows, or how pointers are represented. The address of an element later in an array is always “greater than” the address of an earlier element.
Note the standard does not define relative comparisons (less-than or greater-than) between unrelated objects. You can compare any two objects for equality; 6.5.9 also specifies:
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.
but it does not specify any less-than or greater-than relationship for unrelated objects (not members of a common structure, array, or union), so they all are covered by this statement:
In all other cases, the behavior is undefined.
(For the purposes of pointer comparison, a pointer to a single object is treated as a pointer to the first element of an array of one element, so “one past the last element of the same array object” includes the address just after a single object.)
Upvotes: 8
Reputation: 12708
GCC compiler allows to use relational operators (such as ">", "<", ">=" and "<=") to compare pointers between them, but is it OK to do this, since we do not know in what order (towards higher or lower memory addresses) the stack grows?
That's not a GCC extension, but a characteristic of the C pointer type. But it has a limited use. You can only compare pointers reliably that happen to point to cells of an array. This allows you to know if the pointer A is pointing to a cell that has a lower index in array V than pointer B. Pointers must be to the same type, and they have to be initialized to point to the same or different cells of an array. It's not legal (and you incurr in U.B.) to compare pointers that point to arbitrary locations in general.
The stack has nothing to do in this. Comparing two pointers that point to cells of an array allows you to identify the address with larger index in the array, for example... you can also subtract pointers to get the number of indices that takes to go from pointer A to pointer B.
The idea behind this is that A + i > A
if and only if i
is positive, A + i < A
if and only if i
is negative, and A + i == A
if and only if i
is zero. Remember that adding an integer to A
makes it point to cell size times ahead the value of A
interpreting the pointers as pointing to array elements, so A + 1
will point to the next array cell of the array (and not to the next memory address)
Upvotes: 0