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);
The section C11 6.7.6.3/15 (final sentence) says that top-level qualifiers are not considered for the purposes of determining type compatibility, i.e. it is permitted for the function definition to have different top-level qualifiers on its parameters than the prototype declaration had.
However (unlike C++) it does not say that they are ignored completely. In the case of const
this is clearly moot; however in the case of volatile
and restrict
maybe there could be a difference.
Example:
void f(const int *restrict p);
int main()
{
int a = 42;
const int *p = &a;
f(p);
return a;
}
Does the presence of restrict
in the prototype allow the compiler to optimize out the read of a
for return a;
?
void f(int); void f(int const); int main() {}
is ill-formed? – Bellhoprestrict
-less definition UB I currently can find is 6.2.7 p2 All declarations that refer to the same object or function shall have compatible type; otherwise, the behavior is undefined. But this is out-right absurd: It would be equally applicable toconst
(say, an ABI using a different way to passconst
arguments) and it would makevoid f(const int *restrict);
different, as there is nop
which is declared in the first place (so there is no declaration). – Terenap
will be promote toconst int *restrict
automatically since they are compatible. i think it has the effect of optimization, since in the function body, the type ofp
is indeedconst int * restrict
. i thinkmemcpy
is a good example: manpagez.com/man/3/memcpy. – Enniusrestrict
qualifiers in documentation if and only if they are present in the definition is, as it currently seems, just a conventional thing addressing humans, not the compiler. – Terena