I'm asking this question from the perspective of a compiler developer – I want to know whether a particular potential optimisation is valid (because all programs that the optimisation would break have undefined behavior) or invalid (i.e. it would break some programs whose behavior is defined).
The question is about static restrict array function parameters. I know that restrict means that memory accessed through the restrict pointer isn't accessed any other way during the function body, and static means that the pointer does in fact point to an array of the correct size, but am unsure on the exact details of how these work.
Suppose someone writes the following code, which takes a static restrict array as a function parameter, passes it to an extern function, then conditionally reads through the array afterwards:
extern int bar(int x[static restrict 1]);
int foo(int x[static restrict 1])
{
*x = 1;
int y = bar(x);
int z = 0;
while (y--) z += *x;
return z;
}
My question is: does this code have undefined behaviour if x is a pointer to malloc-ed memory, and bar frees its argument and returns 0? (In other words, this is a question about whether the int x[static restrict 1] argument has to point to an array of 1 int throughout the entire body of the function foo, or whether the requirement applies only at the point of the calls to foo and bar.)
If the requirement applies over the whole function, thus meaning that it would be undefined behavior for bar to free its argument, it would be legal for a compiler to optimise the last three lines into return y * *x;, which has the same result in all situations where x is known to still point to an allocated integer. However, if the requirement applies just on entry, it isn't (with the best available optimisation being someting like return y ? y * *x : 0 instead). So whether the behavior is defined or undefined affects what a compiler is allowed to do with the code.
restrictpointer to anotherrestrictpointer in the same scope - passing arguments to a function is done as per assignment. This is about a muddy fiasco chapter of ISO C called "formal definition of restrict" (C23 6.7.4.2).restrictpointer to another (not just assignments after initialization). However, 6.7.4.2p11 seems to clariify that the rule only applies to assignments that occur after the pointer initially gains its value (and specifically states that the case of passing arestrictpointer to a function that takes arestrictpointer as argument is legal).restrictmeans that memory accessed through therestrictpointer isn't accessed any other way during the function body”: Not quite. That only applies if the memory is modified in any way. If all accesses are reads,restrictdoes not impose any requirements.