Is there any practical difference between the following prototypes?
void f(const int *p);
void f(const int *restrict p);
void f(const int *volatile p);
using 'volatile' on a parameter means to re-read the parameter each time it is used rather than just using some previously read value.
this is 'usually' useless on a passed parameter.
The time for 'volatile' is when the something can change asynchronously to the code execution, such as something modified in an interrupt or I/O value.
Passed parameters are copies and do not change asynchronously.
'Restrict' is a promise by the coder, to the compiler, that certain possible problems can be ignored by the compiler,
such as 'I, the coder, promise that the memory areas of this call to memcpy() do not overlap.
So just use them when they are relevant and don't use them otherwise.