If we have for example f and g defined as:
void f(const int *restrict a, const int *restrict b, int *c){ ... }
void g(const int * a, const int * b, int *c){ ... }
If restrict
is redundant I would expect all three answers to be yes.
Otherwise, why not?
Do not take into account bad programming practices like casting away the const
qualifier.
Objects referenced through a restrict -qualified pointer have a special association with that pointer. All references to that object must directly or indirectly use the value of this pointer. In the absence of this qualifier, other pointers can alias this object.
By Alex Allain. The const keyword allows you to specify whether or not a variable is modifiable. You can use const to prevent modifications to variables and const pointers and const references prevent changing the data pointed to (or referenced).
The const qualifier explicitly declares a data object as something that cannot be changed. Its value is set at initialization. You cannot use const data objects in expressions requiring a modifiable lvalue. For example, a const data object cannot appear on the lefthand side of an assignment statement.
Because the data type being pointed to is const, the value being pointed to can't be changed. We can also make a pointer itself constant. A const pointer is a pointer whose address can not be changed after initialization.
For this case:
void f(const int *restrict a, const int *restrict b, int *c)
restrict
is not redundant. It means the compiler can assume that a
and c
do not alias. For example if the function body were:
int d = *a;
*c = 5;
d = *a;
then the compiler could remove the third line.
This is covered by C11 6.7.3/7:
This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer.
which is saying that if an object is accessed through a
, then the object is not allowed to also be accessed via b
or c
.
The formal definition can be seen in C11 6.7.3.1/4 (Formal definition of restrict):
If L is used to access the value of the object X that it designates, and X is also modified (by any means), then the following requirements apply: T shall not be const-qualified
Here T is the declared type pointed to by a
, i.e. const int
, and L is *a
, and X is whatever int
that a
and c
are pointing to.
Do not take into account bad programming practices like casting away the const qualifier.
The problem is that even in standard C the presence of const
on a pointer is not a binding contract. It is merely a suggestion to the programmer that the callee won't attempt to modify the pointee. The code is in fact permitted to modify the pointee (after casting) as long as the pointee was not originally declared as a const
object.
Therefore, compilers are not able to use const
safely: they still need to examine the contents of the callee to make sure that it isn't lying, if even possible.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With