Am I using restrict
wrong here is it the compilers not optimizing as well as they could?
restrict
-qualification puts constraints on program behavior intended to allow optimizations that otherwise might be assumed unsafe on the basis of possible aliasing. In any particular case, however, that does not imply that the compiler has missed an optimization opportunity if it generates the same code both with and without restrict
. Therefore, I'll focus mainly on the first part of the question.
These are the constraints associated with use of restrict
, from C17 6.7.3.1, somewhat contextualized to your example:
Let D
be a declaration of an ordinary identifier that provides a
means of designating an object P
as a restrict
-qualified pointer
to type T
.
D
is int *restrict bp = &b[0];
.
P
is bp
.
T
is int
.
[...] let B
denote the block.
B
is the whole body of function possibleOverlapOn2ndInt_()
.
In what follows, a pointer expression E
is said to be based on
object P
if (at some sequence point in the execution of B
prior to
the evaluation of E
) modifying P
to point to a copy of the array
object into which it formerly pointed would change the value of E.
No such expressions E
appear in possibleOverlapOn2ndInt_()
, other than bp
itself. In particular, neither a
nor b
is such an expression.
During each execution of B
, let L
be any lvalue that has &L
based on P
.
Neither a[0]
nor b[0]
nor b[1]
satisfies that description. The only such lvalue appearing in possibleOverlapOn2ndInt_()
is bp[0]
.
If L
is used to access the value of the object X
that it designates,
bp[0]
is used to access the object it designates.
and X
is also modified (by any means),
The object designated by bp[0]
is modified (via bp[0]
itself).
then the
following requirements apply: [...]
Every other lvalue used to access the value of X
shall also have its
address based on P
.
This would be violated if a[0]
aliased bp[0]
(and therefore also b[0]
) in any execution of possibleOverlapOn2ndInt_()
.
[...] If these requirements are not met, then the behavior is
undefined.
If the compiler assumed that the behavior of every execution of possibleOverlapOn2ndInt_()
has defined behavior, including with respect to restrict
qualification, then it could generate code as if the function were written like so:
int possibleOverlapOn2ndInt_2(int a[1], int b[2]) {
b[0] = 0xbb;
b[1] = 0xba; // cannot alias b[0]
a[0] = 0xaa; // must not alias b[0], may alias b[1]
return 0xbb + b[1];
}
The compiler is by no means required to make use of that freedom, however.
int *restrict p; ... if (p == somethingNotBasedUponP) { *p = 1;};
the pointer used in the assignment might not be regarded as equivalent torestrict p
, since replacingp
with a pointer to a copy of the associated data wouldn't result in the store being performed with a different target address. – Gin