2011 6.7.3.1 says:
1 Let
Dbe a declaration of an ordinary identifier that provides a means of designating an objectPas a restrict-qualified pointer to typeT.2 If
Dappears inside a block and does not have storage classextern, letBdenote the block. IfDappears in the list of parameter declarations of a function definition, letBdenote the associated block. Otherwise, letBdenote the block ofmain(or the block of whatever function is called at program startup in a freestanding environment).3 In what follows, a pointer expression
Eis said to be based on objectPif (at some sequence point in the execution ofBprior to the evaluation ofE) modifyingPto point to a copy of the array object into which it formerly pointed would change the value ofE. Note that “based” is defined only for expressions with pointer types.4 During each execution of
B, letLbe any lvalue that has&Lbased onP. IfLis used to access the value of the objectXthat it designates, andXis also modified (by any means), then the following requirements apply:Tshall not be const-qualified. Every other lvalue used to access the value ofXshall also have its address based onP. Every access that modifiesXshall be considered also to modifyP, for the purposes of this subclause…
Based on this sentence, I conceived a piece of code:
int main()
{
int A = 5;
int* restrict P;
P = &A;
*P = 10;
int *N = P;
*N = 20;
}
I think that *P is an lvalue L, &*P is the address &L of L, and P is obviously based on &L. Now if we access the object X using L (*P), then as mentioned in the standard:
then the following requirements apply. Among them, there is one:
Every other lvalue used to access the value of
Xshall also have its address based onP.
Let’s continue to look at the code. Next, N is assigned the value of P. Then N should also be based on P. Because when P changes, N also needs to change. So this satisfies:
Every other lvalue used to access the value of
Xshall also have its address based onP.
Then I think that accessing object X via *N is not undefined behavior.
But what I learned before is that,
in each execution of the block where the restrict pointer P is declared, if an object that can be accessed (directly or indirectly) by P is modified by any means, then all accesses to that object in that block must be performed via P; otherwise, the behavior is undefined.
Here I actually used *N (another ordinary pointer) to access the object X, so I am very confused now:
- Is my program strictly in line with the standard (not undefined behavior)?
- If my program is correct, does this mean that the object pointed to by the pointer modified by 'restrict' can be accessed using other ordinary pointers?
- If my program is wrong, then how should we understand the words in the C 2011 standard?