Reputation: 94459
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
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
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
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