Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is restrict redundant for a const qualified pointer?

Tags:

c

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){ ... }
  1. Assumming f and g have equivalent bodies, are they the same from the caller point of view?
  2. In the callee, can we make the same assumptions on the parameters?
  3. Has the compiler the same optimization opportunities?

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.

like image 808
vicencb Avatar asked Oct 06 '16 21:10

vicencb


People also ask

What is restrict qualified pointer?

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.

What is const correctness in c++?

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).

What is const qualified?

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.

Can I modify a const pointer?

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.


2 Answers

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.

like image 112
M.M Avatar answered Oct 11 '22 21:10

M.M


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.

like image 26
Rufflewind Avatar answered Oct 11 '22 19:10

Rufflewind