Frerich Raabe
Frerich Raabe

Reputation: 94459

Is it legal to compare a pointer to the beginning of an array with a pointer of the same type pointing before the beginning of the array?

Is this program legal C? If so, please support your claim (either way) with references to one of the language standards.

void f(char *p) {
    char *q = p - 1;
    (void)( q < p );
};

int main(void) {
    char arr[] = "Hello";
    f( arr );
}

In particular, I'm interested in whether the q < p comparison is legal or not.

Upvotes: 3

Views: 161

Answers (3)

lulijeta
lulijeta

Reputation: 908

I don't know about legal but it sure does not make sense. p points to the array, which means holds the address of the array. q points to one address block before the array. Whenever you compare them you'll be comparing the address of two sequential address blocks. The result will always be true, since you are basically comparing p and p-1

Upvotes: -1

Fred Foo
Fred Foo

Reputation: 363797

No, this is not legal. A pointer must either point into an array, or one past the end of it, or be null.

ISO C11, Appendix J.2 "Undefined behavior", says behavior is undefined when:

Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6).

This is the case in the line

char *q = p - 1;

when p == &arr[0], and a single line having UB causes the whole program to have UB. Note that you don't have to compare the pointer or dereference it or anything. The subtraction is enough.

Upvotes: 3

user529758
user529758

Reputation:

No, it isn't. Using a pointer which doesn't point to an element of the array or one past its end (i. e. which isn't in the range [&arr[0], &arr[size]]) invokes undefined behavior.

C11 Standard, 6.5.6.8 ("Additive Operators"):

If both the pointer operand and the result [of P + N] point to elements of the same array object, or one past the last element of the array object, the evaluation shall not produce an overflow; otherwise, the behavior is undefined.

(emphasis mine)

Upvotes: 4

Related Questions