Regarding restrict qualifier

V

venkat

Hi,

i came across restrict qualifier while looking the code. I haven't
able to understand what does this do?. Can some one help me how does
this makes the things restrict to an specified objects. It will be
good, if explained with example.

Appriciate your help in this regard.

Thanks,
Vikas.
 
K

karthikbalaguru

Hi,

i came across restrict qualifier while looking the code. I haven't
able to understand what does this do?. Can some one help me how does
this makes the things restrict to an specified objects. It will be
good, if explained with example.

Appriciate your help in this regard.

One of the new features in the recently approved C standard C99, is
the restrict pointer qualifier. This qualifier can be applied to a
data pointer to indicate that, during the scope of that pointer
declaration, all data accessed through it will be accessed only
through that pointer but not through any other pointer. The 'restrict'
keyword thus enables the compiler to perform certain optimizations
based on the premise that a given object cannot be changed through
another pointer. Now you're probably asking yourself, "doesn't const
already guarantee that?" No, it doesn't. The qualifier const ensures
that a variable cannot be changed through a particular pointer.
However, it's still possible to change the variable through a
different pointer.

Referred from http://www.devx.com/tips/Tip/13825


Karthik Balaguru
 
C

christian.bau

Hi,

i came across restrict qualifier while looking the code. I haven't
able to understand what does this do?. Can some one help me how does
this makes the things restrict to an specified objects. It will be
good, if explained with example.

First an example for motivation of "restrict". Take a loog at this
function:

void store_average (int* dst, size_t count, int* src) {
size_t i;
for (i = 0; i < count; ++i)
dst = (src [0] + src [1] + src [2] + src [3]) / 4;
}

Looks like the same value is stored into all elements of dst, so you
would expect that an optimising compiler would calculate (src [0] +
src [1] + src [2] + src [3]) / 4 only once and store it (count) times.
Unfortunately, that doesn't work. Someone could write code like this:

int a [100];
/* Store some values into a */
store_average (a, 100, &a[50]);

As you can see, a different value has to be stored into a [51] and
consecutive elements, so the compiler is not allowed to do that
optimisation. Very annoying, because no sane person would call
store_average that way. So you try to improve it by changing the
function like this:

void store_average (int* dst, size_t count, const int* src) {
size_t i;
for (i = 0; i < count; ++i)
dst = (src [0] + src [1] + src [2] + src [3]) / 4;
}

You'd think that the elements of src can't change, but you are wrong:
The "const" only means that src [0] to src [3] cannot be changed using
the pointer src, but they can be changed using the pointer dst. So the
compiler still cannot optimise the function the way you want. Now you
change to

void store_average (int* dst, size_t count, int* restrict src) {
size_t i;
for (i = 0; i < count; ++i)
dst = (src [0] + src [1] + src [2] + src [3]) / 4;
}

Now the compiler can optimise the function! "int* restrict src" means:
You, the programmer, guarantee to the compiler that anything that is
read by using the pointer src, directly or indirectly, is not changed
by using a pointer that is not derived from the pointer src. And also,
you guarantee that anything that is modified by using the pointer src
is not accessed by using a different pointer.

In other words, you guarantee to the compiler that storing values into
the array dst doesn't change the values src [0] to src [3], and
therefore the compiler can now optimise the function by calculating
the average only once instead of (count) times.

There is a variation of this, if you combine const and restrict:

void store_average (int* dst, size_t count, const int* restrict src) {
size_t i;
for (i = 0; i < count; ++i)
dst = (src [0] + src [1] + src [2] + src [3]) / 4;
}

Here, "const int* restrict src" means: You, the programmer, guarantee
to the compiler that anything that is accessed through the pointer src
is not modified in any way. In this example, it doesn't make much
difference. Without the "const", you would guarantee that src [0] to
src [3] are only changed by using the pointer src, directly or
indirectly. And the compiler can look at the code and see that you
don't use src to change these values, so they stay unchanged. But in
other situations, you could for example pass the pointer src to a
function that the compiler doesn't know, and that function might
change src [0]. The "const int* restrict src" guarantees to the
compiler that this doesn't happen.

Now what happens if you call

store_average (a, 100, &a[50]);

? You guaranteed to the compiler that src [0] to src [3] are not
changed. You lied to the compiler. As a result, there are no
guarantees at all what this code will do (it invokes undefined
behaviour). Whatever the code does, it is your fault because you
called the function incorrectly. On the other hand, the code will
likely run a lot faster, which is the purpose of "restrict"
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top