Suppose I have a function which takes some pointer parameters - some non-const, through which it may write, and some const through which it only reads. Example:
void f(int * a, int const *b);
Suppose also that the function does not otherwise write to memory (i.e. doesn't use global variables, fixed addresses, recasting the const pointers as non-const and such tricks).
Now, is it sufficient (as per the C language standard), for achieving the benefits of restrict
for all reads within f()
, to only restrict
the output parameters? i.e. in the example, restrict a
but not b
?
A simple test (GodBolt) suggests such restriction should be sufficient. This source:
int f(int * restrict a, int const * b) {
a[0] += b[0];
return a[0] + b[0];
}
int all_restricted(int * restrict a, int const * restrict b) {
a[0] += b[0];
return a[0] + b[0];
}
int unrestricted(int * a, int const * b) {
a[0] += b[0];
return a[0] + b[0];
}
Produces the same object code for x86_64:
f:
mov eax, DWORD PTR [rsi]
mov edx, DWORD PTR [rdi]
add edx, eax
mov DWORD PTR [rdi], edx
add eax, edx
ret
all_restricted:
mov eax, DWORD PTR [rsi]
mov edx, DWORD PTR [rdi]
add edx, eax
mov DWORD PTR [rdi], edx
add eax, edx
ret
unrestricted:
mov eax, DWORD PTR [rsi]
add eax, DWORD PTR [rdi]
mov DWORD PTR [rdi], eax
add eax, DWORD PTR [rsi]
ret
but that's not a general guarantee.
restrict
. What did you expect? – Knockaboutrestrict
only matters when data are modified. Thus modification of data pointer by a restricted pointera
mean that all other access to this data must be done viaa
. So any access via pointerb
can never alias data pointed bya
. So evenconst
is no longer necessary for optimization and in practice it never is. See godbolt.org/z/a6bGYvhsG – Courserconst
is not necessary for the optimization. I was asking whether the restrict on the outputs is sufficient. You seem to be saying that it is... can you back this up with a quote from the standard? – Quanint * restrict a
implies that the pointera
given to the function does not overlap other referenced data. All changes to*a
are directly visible in the function.int const * b
, withoutrestrict
does not have this guarantee for*b
. Theconst
implies the function will not directly change its*b
, yet changing*a
, as ina[0] += b[0];
still could change*b
viaf(p, p);
2) Posted assembly is an indicator, but not sufficient. Mis-called functions, that prevents an unsafe argument, result in UB. Emitted code does not have to be different. – Yuccarestrict
ona
does not helpb
to have somerestrict
properties in any way – Yucca