I have trouble understanding what restrict
means in terms with calling functions with already restricted variables.
Wikipedia tells me:
The restrict keyword is a declaration of intent given by the programmer to the compiler. It says that for the lifetime of the pointer, only it or a value directly derived from it (such as pointer + 1) will be used to access the object to which it points.
I have these three example functions:
void a(int const *p1, int const *p2) {
...
}
void b(int *restrict p1, int *restrict p2) {
...
}
void c(int *p1, int *p2) {
...
}
and I would call them each from a function
foo(int *restrict p1, int *restrict p2) {
a(p1, p2);
b(p1, p2);
c(p1, p1+1);
}
which of them would keep the restrict
promise that function foo
declaration makes?
The three cases would be:
Function a
doesn't modify anything, so that would surely hold.
How about b
, are the parameters to it "directly derived" from the foo
's pointers? Am I braking the promise I'm giving in foo
declaration if I modify the p1
or p2
in b
?
Does the situation change in c
from the previous scenario if the parameters aren't restricted in any way, and I edit for example p2 in c
?
Here are the promises you are making:
void foo(int *restrict p1, int *restrict p2) {
// a() can't modify p1[...] or p2[...]
a(p1, p2);
// b() CAN modify p1[...] or p2[...]
// Note that you are still making this promise if you don't use
// "restrict" in the declaration of b()
b(p1, p2);
// c() CAN modify p1[...] but not p2[...]
c(p1, p1+1);
}
You can't be sure that the promises you are making are correct unless you know what the functions do and how they are called.
For example, this is wrong:
int global;
void a(int const *p1, int const *p2) {
// Since p1 == &global, we can break the promise here
// by accessing *p1 through the name "global"...
// Even though this function is perfectly okay by itself!
global = 5;
}
void foo(int *restrict p1, int *restrict p2) {
// We have a promise that a() won't modify p1[...]
// BECAUSE: "restrict" promises that all p1 modifications
// go through p1, since p1 is passed "const" a() is not
// supposed to modify *p1, but p1 = &global, and a() modifies
// global... BOOM!
// Even though this function is perfectly okay by itself...
a(p1, p2);
}
int main() {
int y;
// Illegal! Once you pass &global to foo(), BOOM!
foo(&global, &y);
}
This is why restrict
is a bit tricky. You can't figure out if it is correct or not based on the function signatures alone.