The C language imposes no requirements on bounds checking of arrays. That is part of what makes it fast. That being said, compilers can and do perform check in some situations.
For example, if I compile with -O3
in gcc and replace return p[~0LLU];
with return p[10];
I get the following warning:
x1.c: In function ‘foo’:
x1.c:6:10: warning: ‘*((void *)&x+60)’ is used uninitialized in this function [-Wuninitialized]
return p[10];
I get a similar warning if I use -10
as the index:
gcc -g -O3 -Wall -Wextra -Warray-bounds -o x1 x1.c
x1.c: In function ‘foo’:
x1.c:6:10: warning: ‘*((void *)&x+-20)’ is used uninitialized in this function [-Wuninitialized]
return p[-100];
So it does seem that it can warn about invalid negative values for an array index.
In your case, it seems for this compiler that the value ~0LLU
is converted to a signed value for the purposes of pointer arithmetic and is viewed as -1.
Note that this check can be fooled by putting other initialized variables around x
:
int foo() {
int y[10] = {0};
int x[10] = {0};
int z[10] = {0};
int *p = &x[5];
printf("&x=%p, &y=%p, &z=%p\n", (void *)x, (void *)y, (void *)z);
return p[10] + y[0] + z[0];
}
This code produces no warnings even though p[10]
is out of bounds.
So it's up to the implementation if it wants to perform a out-of-bounds check and how it does it.