restrict指针赋值语义及假设代码正确性、UB与作用域问题问询
restrict Questions 1. Semantics of Assigning a restrict Pointer to a Non-restrict Pointer
The restrict qualifier is a programmer’s promise to the compiler: for the lifetime of the restrict pointer, any modification to the object it points to must be done through that pointer or a pointer directly derived from it (e.g., y + 0, y + 1, etc.).
When you assign a restrict pointer to a non-restrict pointer (like int *a = y where y is restrict), you’re creating an alternative way to access the same object (or array elements). This doesn’t inherently violate the restrict contract—as long as all modifications to the original object are still done through the restrict pointer or its derivatives (including the non-restrict pointer you created).
The key impact is on compiler optimizations: the compiler can still assume no aliasing for the original restrict pointer’s target, but if the non-restrict pointer is used to access other memory (like y + N where N != 0), the compiler loses the ability to assume those locations don’t alias with other pointers (like x in your code).
2. Analysis of the Provided Code
Let’s break down the code, including edge cases and scope questions:
Code Recap
#define N 1 // what if it's 0? void foo(int *x, int * restrict y) { *x = 42; *y = 0; // compiler can assume *x is still 42. { int *a = y + N; *a = 123; // compiler can no longer assume *x is 42. } // does the new scope matter in this case? }
Key Observations:
When
N = 1:- The first comment is correct: Since
yisrestrict, the compiler assumesxdoes not aliasy. Modifying*yhas no effect on*x, which remains 42. - The second comment is also correct:
a = y +1points to the next integer aftery. Therestrictqualifier only applies to the objectypoints to (not the entire array), so the compiler can’t rule out thatxpoints toy+1. Modifying*ameans*xmight have changed, so the assumption about*xbeing 42 is invalidated. - No undefined behavior (UB) exists here if
ypoints to the first element of an array of at least 2 integers (soy+1is a valid pointer).
- The first comment is correct: Since
When
N = 0:- The second comment is wrong:
a = y +0is equivalent toa = y. Sinceyisrestrict, the compiler still assumesxdoesn’t aliasy, so modifying*a(which is*y) doesn’t affect*x. The compiler can still safely assume*xis 42. - No UB here as long as
ypoints to a valid integer (which is required for*y =0anyway).
- The second comment is wrong:
Does the inner scope matter?
No, the new scope has no impact on the compiler’s aliasing assumptions. The scope ofaonly determines where the variable is accessible, but the compiler still tracks the relationship betweenaandy(and the potential for aliasing withx) regardless of whereais declared. The modification to*aaffects the compiler’s assumptions aboutxregardless of the block it’s in.Undefined Behavior Risks:
UB only occurs if:- The caller passes
xthat aliasesy(violating therestrictpromise ofy). ydoes not point to a sufficient array whenN >0(e.g.,N=1butypoints to a single integer, makingy+1an invalid pointer and*a=123UB).
- The caller passes
内容的提问来源于stack exchange,提问作者Dan M.

