The whole point of restrict
is to promise accesses through one pointer don't alias another. That said, there are examples where overlapping memory addresses wouldn't imply aliasing. For example:
int* arr_ptr0 = &arr[0];
int* arr_ptr1 = &arr[1];
for (int i=0;i<10;++i) {
*arr_ptr0 = *arr_ptr1;
arr_ptr0 += 2;
arr_ptr1 += 2;
}
The thing is, these pointers actually do point to overlapping memory! For this particular example, guides like this say, e.g.:
It is valid . . . to point into the same array object, provided the range of elements accessed through one of the pointers does not overlap with the range of elements accessed through the other pointer.
My question is: What granularity is "elements"?
For example, suppose I have an array of type struct Foo
. Do I really need to ensure that I don't access the same range of elements (Foo
s), even if the parts I access are disjoint? Here's a simple, scalar example:
struct Foo { int i; float f; };
void f(struct Foo*restrict foo0, struct Foo*restrict foo1) {
foo0->i = 6;
foo1->f = 19.0f;
}
void g(struct Foo* foo) {
f(foo,foo); /* problem? */
}
You can run into similar issues with pointers to different types (e.g. char
vs. int
), but perhaps the structure example above is more clear.
The relevant text of the standard is 6.7.3.1 Formal definition of restrict:
Your first example (the interleaved array) is perfectly valid by my reading of the standard.
The second example with the struct is less clear, and depends on whether the use of the
->
operator (your wrote.
but meant->
) withfoo0
(orfoo1
) means that*foo0
(orfoo1
) is "used to access the value of the object that it designates". This is not clear to me since the struct is not used as a value; only its members are.The
restrict
keyword is strictly advisory to the compiler that the application won't modify the same addresses through another pointer not derived from it, within the type qualified scope.Nothing actually restricts the application from doing so though. However, it's safe to assume modifying an address that's accessed through a
restrict
qualified pointer through something other than thatrestrict
qualified pointer will result in undefined behavior (beware dragons).