473,738 Members | 1,949 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

restrict keyword from ISO C99?

Can someone give me a short example as how to best use this keyword in
your code?

This is my understanding: by definition restrict sounds like it is
suppose to restrict access to memory location(s) pointed to, so that
only one declared pointer can store that address and access the data in
those memory blocks, where I the data in those location(s) can be changed.

Is that a correct understanding?

Thanks,

Brian

P.S. I'm slowly making my way through the ISO C99 standard.
Nov 14 '05 #1
7 2670
tweak wrote:
Can someone give me a short example
as how to best use this keyword in your code?
#include <string.h>

void *memcpy(void *restrict dest,
const void *restrict src, size_t n);
This is my understanding: by definition restrict sounds like
it is suppose to restrict access to memory location(s) pointed to,
so that only one declared pointer
can store that address and access the data in those memory blocks,
where I the data in those location(s) can be changed.

Is that a correct understanding?


Probably not.

The restrict keyword is a promise by the programmer to the compiler
that the destination [dest] array is *not* an alias
for any part of the source [src] array -- they don't overlap.
But there is, in general, no way for the compiler to determine
whether they are actually aliases or not so the programmer can lie.
The behavior is *undefined*
if copying takes place between objects that overlap.
Nov 14 '05 #2

"tweak" <xb**********@c ox.net> wrote in message
news:bdMAc.730$ DQ4.264@fed1rea d05...
Can someone give me a short example as how to best use this keyword in
your code?

This is my understanding: by definition restrict sounds like it is
suppose to restrict access to memory location(s) pointed to, so that
only one declared pointer can store that address and access the data in
those memory blocks, where I the data in those location(s) can be changed.

Is that a correct understanding?

Partly. When you use the keyword, you take responsibility for the pointers
not interfering with each other, and tell the compiler not to skip any
optimizations you request which might lead to changes in the order of memory
access.

int func(float * restrict a, float * restrict b, int n){
for(int i=0; i < n; ++i)a[i] += b[i];
}

You tell the compiler not to be concerned that b[] may be changed as a
result of storing into a[], so it is OK to read as far ahead in a[] and b[]
as might be needed to generate fast code. Without restrict, it would not be
OK for the compiler to use parallel instructions, for example. With
restrict, you rule out cases such as a happening to be equal to b+1, in
which case each result feeds into the next operation. Should you compile
this with restrict, and then violate the pledge you made, the results are
undefined.
You may be having difficulty distinguishing this from the implications of
const. const merely tells the compiler to stop you from modifying
explicitly an object which you said would not be modified. It doesn't tell
the compiler to perform optimizations on that account, nor would it prevent
you from running this example with a == b+1. I found it difficult to sort
these out myself.
restrict seems to be a parting of the ways which distinguishes C99 from C89
and C++. No more "C/C++"
Nov 14 '05 #3
E. Robert Tisdale wrote:
tweak wrote:
Can someone give me a short example as how to best use this keyword in
your code?

#include <string.h>

void *memcpy(void *restrict dest,
const void *restrict src, size_t n);
This is my understanding: by definition restrict sounds like
it is suppose to restrict access to memory location(s) pointed to,
so that only one declared pointer
can store that address and access the data in those memory blocks,
where I the data in those location(s) can be changed.

Is that a correct understanding?

Probably not.

The restrict keyword is a promise by the programmer to the compiler
that the destination [dest] array is *not* an alias
for any part of the source [src] array -- they don't overlap.
But there is, in general, no way for the compiler to determine
whether they are actually aliases or not so the programmer can lie.
The behavior is *undefined*
if copying takes place between objects that overlap.


For clarity:

aliases == variables?
objects == memory locations (&) ?

So if an array with four elements (e.g. char name[4]) occupied 0x01
through 0x05, where 0x05 is '\0', and another array with four elements
(e.g. char fullname[4]) occupied 0x04 through 0x08, where 0x08 is '\0',
then overlap would occur. And the restrict keyword specifies that the
programmer promises to keep the overlapping from occurring, but the
compiler cannot confirm? Is this a better understanding?

Thanks,

Brian
Nov 14 '05 #4
Tim Prince wrote:
"tweak" <xb**********@c ox.net> wrote in message
news:bdMAc.730$ DQ4.264@fed1rea d05...
Can someone give me a short example as how to best use this keyword in
your code?

This is my understanding: by definition restrict sounds like it is
suppose to restrict access to memory location(s) pointed to, so that
only one declared pointer can store that address and access the data in
those memory blocks, where I the data in those location(s) can be changed.

Is that a correct understanding?


Partly. When you use the keyword, you take responsibility for the pointers
not interfering with each other, and tell the compiler not to skip any
optimizations you request which might lead to changes in the order of memory
access.

int func(float * restrict a, float * restrict b, int n){
for(int i=0; i < n; ++i)a[i] += b[i];
}

You tell the compiler not to be concerned that b[] may be changed as a
result of storing into a[], so it is OK to read as far ahead in a[] and b[]
as might be needed to generate fast code. Without restrict, it would not be
OK for the compiler to use parallel instructions, for example. With
restrict, you rule out cases such as a happening to be equal to b+1, in
which case each result feeds into the next operation. Should you compile
this with restrict, and then violate the pledge you made, the results are
undefined.
You may be having difficulty distinguishing this from the implications of
const. const merely tells the compiler to stop you from modifying
explicitly an object which you said would not be modified. It doesn't tell
the compiler to perform optimizations on that account, nor would it prevent
you from running this example with a == b+1. I found it difficult to sort
these out myself.
restrict seems to be a parting of the ways which distinguishes C99 from C89
and C++. No more "C/C++"

So the programmer takes the responsibility to manage the modifyable
pointers, allowing the compiler to generate faster machine code. But
because the compiler cannot confirm the programmer did not break his
promise, there is a possibility of undefined behavior should the
programmer break his promise. And the result is better machine code,
so if I disassemble after compiling with optimizations on, I should see
better assembly code, right?

And in your example of a == b+1, you have performed pointer math on b
that you had promised that you would not perform? Is the promise made
on the memory locations, what's contained in those locations, or both?

Thanks,

Brian
Nov 14 '05 #5

"tweak" <xb**********@c ox.net> wrote in message
news:%HOAc.740$ DQ4.283@fed1rea d05...
Tim Prince wrote:
"tweak" <xb**********@c ox.net> wrote in message
news:bdMAc.730$ DQ4.264@fed1rea d05...
Can someone give me a short example as how to best use this keyword in
your code?

This is my understanding: by definition restrict sounds like it is
suppose to restrict access to memory location(s) pointed to, so that
only one declared pointer can store that address and access the data in
those memory blocks, where I the data in those location(s) can be changed.
Is that a correct understanding?
Partly. When you use the keyword, you take responsibility for the pointers not interfering with each other, and tell the compiler not to skip any
optimizations you request which might lead to changes in the order of memory access.

int func(float * restrict a, float * restrict b, int n){
for(int i=0; i < n; ++i)a[i] += b[i];
}

You tell the compiler not to be concerned that b[] may be changed as a
result of storing into a[], so it is OK to read as far ahead in a[] and b[] as might be needed to generate fast code. Without restrict, it would not be OK for the compiler to use parallel instructions, for example. With
restrict, you rule out cases such as a happening to be equal to b+1, in
which case each result feeds into the next operation. Should you compile this with restrict, and then violate the pledge you made, the results are undefined.
You may be having difficulty distinguishing this from the implications of const. const merely tells the compiler to stop you from modifying
explicitly an object which you said would not be modified. It doesn't tell the compiler to perform optimizations on that account, nor would it prevent you from running this example with a == b+1. I found it difficult to sort these out myself.
restrict seems to be a parting of the ways which distinguishes C99 from C89 and C++. No more "C/C++"

So the programmer takes the responsibility to manage the modifyable
pointers, allowing the compiler to generate faster machine code. But
because the compiler cannot confirm the programmer did not break his
promise, there is a possibility of undefined behavior should the
programmer break his promise. And the result is better machine code,
so if I disassemble after compiling with optimizations on, I should see
better assembly code, right?

You have no guarantee of "better" code, but if you use a "vectorizin g" or
pipelining compiler, it should not perform those optimizations without at
least one of the restricts, or alternatively some option which gives more
freedom than C allows.
And in your example of a == b+1, you have performed pointer math on b
that you had promised that you would not perform? Is the promise made
on the memory locations, what's contained in those locations, or both?

It doesn't matter if you violate the restrict to the extent of having
overlapping read-only ranges of memory locations. What matters is that one
pointer isn't used to modify data pointed to by another. Strictly, of
course, you are promising no overlap in memory ranges. It's probably better
to stick to that from a maintainability point of view, in case you started
modifying the target of a pointer, and forgot that it overlapped the target
of another.
Nov 14 '05 #6
In article <bdMAc.730$DQ4. 264@fed1read05> , tweak <xb**********@c ox.net>
wrote:
Can someone give me a short example as how to best use this keyword in
your code?

This is my understanding: by definition restrict sounds like it is
suppose to restrict access to memory location(s) pointed to, so that
only one declared pointer can store that address and access the data in
those memory blocks, where I the data in those location(s) can be changed.

Is that a correct understanding?


Two examples why restrict is useful:

int calc_area (int* width, int* height) {
*width = 5;
*height = 6;
return (*width) * (*height);
}

int f (const int* p, int* q) {
int x = *p;
*q = x + 1;
return *p;
}

In the first function, you would assume that the function returns 30, so
an optimising compiler can avoid reading *width and *height and
multiplying these values. Sadly, this is wrong. If I write

int x;
int a = calc_area (&x, &x);

the result is 36, not 30. An optimising compiler is forced to store 5
into *width, then store 6 into *height, then read *width, then multiply
that value by 6 and return the result.

In the second function, you would assume that the value returned is
always equal to x. Sadly, this is wrong, too. If I write

int x = 5;
int a = f (&x, &x);

then x will be changed to 6, and the value returned is six, not five.
"const int* p" only means that you cannot store to the object *p through
the pointer *p itself, but the same object can be modified by other
means - for example by storing to *q.

In both functions, the compiler is forced to produce slow code, to
handle situations that will never arise in practice. That is what
"restrict" is for.

If you declare a restrict pointer object, like

int* restrict p;

then all pointer values from then on fall into two categories: Pointer
values that are derived from p, and pointer values that are not derived
from p. Roughly speaking, pointer values derived from p are pointer
values that are calculated by starting with p, and adding or subtracting
to it in arbitrary complicated way. For example,

int a [100];
int* restrict p = &a [0];
int* q = p + 1;
int* r = q - 1;
int* s = &a [0];

q and r are derived from p. s is not derived from p. Even though r == s,
one is derived from p, the other is not.

You promise the compiler two things:

1. Any object that is modified through a pointer based on p, is not
accessed or modified through any pointer that is not based on p.
2. Any object that is modified through a pointer that is not based on p,
is not accessed or modified through any pointer that is based on p.

Declaring a "const restrict" pointer object is stronger. If you have

const int* restrict p = &a[0];

for example, then your promise to the compiler is:

Any object that is accessed through a pointer based on p is not modified
by any means whatsoever.

What does that mean for the examples above: If you wrote

int calc_area (int* restrict width, int* restrict height) { ... }

you promise that assigning to *height does not change *width and vice
versa (just read the rules above carefully). Actually, using one
restrict pointer would have had the same effect. As a result, the
compiler can assume that the result of this function is always 30.

In the second function, if you wrote

int f (const int* restrict p, int* q) { ... }

you would promise to the compiler that *p is not modified in that
function by any means, so you promse that q does not point to *p. An
optimising compiler needs to read *p only once and knows that it cannot
change its value in that function.
Nov 14 '05 #7
In <bdMAc.730$DQ4. 264@fed1read05> tweak <xb**********@c ox.net> writes:
Can someone give me a short example as how to best use this keyword in
your code?

This is my understanding: by definition restrict sounds like it is
suppose to restrict access to memory location(s) pointed to, so that
only one declared pointer can store that address and access the data in
those memory blocks, where I the data in those location(s) can be changed.

Is that a correct understanding?


Your description is not very coherent, so it's hard to tell whether your
understanding is correct or not. This is one of the cases where it's
better to avoid the normative text of the standard and focus on the
examples:

7 EXAMPLE 1 The file scope declarations

int * restrict a;
int * restrict b;
extern int c[];

assert that if an object is accessed using one of a, b, or c,
and that object is modified anywhere in the program, then it is
never accessed using either of the other two.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

28
6421
by: gc | last post by:
Hi, What is the purpose of the restrict keyword? gc
11
2153
by: pemo | last post by:
If you were to compile/run the code below, and get the result '30', I'd be very interested to know what compiler you're using - and its optimisation settings #include <stdio.h> int test(int * a, int * b) { *a = 5; *b = 6;
12
2500
by: Me | last post by:
I'm trying to wrap my head around the wording but from what I think the standard says: 1. it's impossible to swap a restrict pointer with another pointer, i.e. int a = 1, b = 2; int * restrict ap = &a; int * restrict bp = &b;
21
6521
by: Niu Xiao | last post by:
I see a lot of use in function declarations, such as size_t fread(void* restrict ptr, size_t size, size_t nobj, FILE* restrict fp); but what does the keyword 'restrict' mean? there is no definition found in K&R 2nd.
2
3889
by: Frederick Gotham | last post by:
I did a search through the C++ Standard there, and couldn't find any mention of "restrict" or "__restrict__". Firstly, could someone please confirm whether "restrict" is mentioned in the C++ Standard? A quick search of the web shows up a few pages which imply that C++ has a "__restrict__" keyword... is there any truth to this? Basically my question is:
0
2986
by: copx | last post by:
Restrict keyword questions How far does the guarantee that an object is not accessed through another pointer go? I mean, all examples I have seen are simple stuff like: int f (int *restrict x, int *restrict y) { *x = 0; *y = 1; return *x;
23
4833
by: raashid bhatt | last post by:
what is restrict keyword used for? eg int *restrict p;
0
8968
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8787
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9473
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
9259
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9208
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8208
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6750
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
2
2744
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2193
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.