I'm reading the section on array arithmetic in K&R and came across something curious. I posted the whole paragraph for context, but I'm mainly focused on the bold part:
If
p
andq
point to members of the same array, then relations like==
,!=
,<
,>=
, etc. work properly. For example,p < q
is true ifp
points to an earlier member of the array thanq
does. Any pointer can be meaningfully compared for equality or inequality with zero. But the behavior is undefined for arithmetic or comparisons with pointers that do not point to members of the same array. (There is one exception: the address of the first element past the end of an array can be used in pointer arithmetic.)
I got some answers here (C pointer arithmetic for arrays) but I have doubts described below:
I have a doubt in this since the following code seems to work with dereferencing and comparisons without throwing any exception or errors:
#include <stdio.h>
int main() {
int a[5] = { 1, 2, 3, 4, 5 };
int b[5] = { 1, 2, 3, 4, 5 };
int *p = &a[7];
int *q = &b[3];
printf("%d\n", p);
printf("%d\n", q);
printf("%d\n", q > p);// relational from different arrays
printf("%d", *p); // dereferencing also seems to work
}
Can anyone help with this?
The code should throw an error
CodePudding user response:
Your code has undefined behavior in multiple places, but the C language does not define what happens in case of undefined behavior: anything can happen. There is no exception or error to be thrown, the program may crash, produce unexected results or seem to work and produce expected results... anything goes, nothing can be expected.
There is undefined behaviour in these places:
int *p = &a[7];
you compute the address of a non existing element of thea
array beyond the end of the array and not the element just after the end.printf("%d\n", p);
you pass a pointer toint
whereprintf
expects anint
. You should writeprintf("%p\n", (void *)p);
printf("%d\n", q);
same as aboveprintf("%d\n", q > p);
using the value ofp
which was not initialized to a valid expressionprintf("%d", *p);
dereferencing invalid pointerp
.
CodePudding user response:
You are working with undefined behavior. This means you cant rely on it - it may work well one day, may not work at all on another. But no matter what - you cant trust it.
And thats why undefined behavior is so dangerous sometimes - it may work fine until failing horribly one day with no perrior warning.