473,569 Members | 2,645 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

'restrict' in plain English?

Me
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;

int *temp = bp;
bp = ap;
ap = bp;

is undefined.

2. it doesn't support exactly overlapping memory, i.e.

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}

float a[] = { 1, 2, 3 };
v3add(a, a);

is undefined.

3. the library changes may break (correct?) existing code, i.e.

FILE *fopen(const char * restrict filename, const char * restrict
mode);

FILE *f = fopen("foo.rt", "rt");

if the compiler transforms this to:

static const char str[] = "foo.rt";
FILE *f = fopen(str, str + 4);

the code becomes undefined.

Is any of this correct?

Mar 6 '06 #1
12 2482
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:
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;

int *temp = bp;
This should require a cast, I believe.
bp = ap;
ap = bp;

is undefined.
Why do you think this is undefined? It might be, depending on what
you do with the pointers.
2. it doesn't support exactly overlapping memory, i.e.

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}

float a[] = { 1, 2, 3 };
v3add(a, a);
The function itself is well defined, the call to the function is, I
suppose, technically undefined. Although there is no problem with
this actual use.
is undefined.

3. the library changes may break (correct?) existing code, i.e.

FILE *fopen(const char * restrict filename, const char * restrict
mode);

FILE *f = fopen("foo.rt", "rt");

if the compiler transforms this to:

static const char str[] = "foo.rt";
FILE *f = fopen(str, str + 4);

the code becomes undefined.
No, the code above is well-defined. In fact, it is possible that a
compiler might generate this code itself, as merging string literals
is allowed by the standard and some compilers do it.
Is any of this correct?


The restrict qualifier only has meaning in terms of modifying an
object. That's why there is no problem at all with your third
example. The two strings passed to fopen() are const qualified and
the function does not try to modify them.

Your second example is not really undefined because even though
modifying objects pointed to by 'a' also modifies objects pointed to
by 'b', there is no use of the value of any object pointed to by 'b'
after it is modified by the write through 'a'.

Consider this version of your second example:

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0]; /* a[0] = b[0] = 2 */
a[1] += b[0]; /* a[1] = 2 + 2 = 3 */
a[2] += b[0]; /* a[1] =
}

int main()
{
float a[] = { 1, 2, 3 };
v3add(a, a);
/* printf() the values of 'a' */
return 0;
}

Without the 'restrict' keyword above, the compiler cannot assume that
'a' and 'b' point do not point to the same area. Specifically, they
can't assume that b[0] is not changed by any of the assignments
through 'a'. With the 'restrict' keyword it can assume, and generate
code based on that assumption. It is quite likely that the code will
actually read b[0] only once.

The concept of the restrict type qualifier is to inform the compiler
that the object(s) pointed to by a particular pointer will not be
modified other than through that pointer, or a pointer derived from
it.

Consider:

const int ci = 12;

void some_func(void)
{
some_global_fun ction();
if (ci == 12)
{
printf("Yep, it's still 12\n");
}
}

....and:

void other_func(int restrict *ip)
{
*ip = 12;
some_global_fun ction();
if (*ip == 12)
{
printf("Yep, it's still 12\n");
}
}

In both cases above, the compiler is justified in omitting the test
and making the printf() call unconditional.

This is true in the first place because it depends on the value of a
const object remaining the same.

In the second case, this is true because you have promised the
compiler, when you tell it its argument is restrict qualified, that
absolutely nothing that happens in the program will modify what ip
points to without doing so through ip.

This allows certain optimizations that would not be possible
otherwise, namely the compiler does not have to perform the test "if
(*ip == 12)". You have promised the compiler that whatever happens
during the call to "some_global_fu nc()", the object(s) pointed to by
ip will not be modified.

If the object(s) pointed to by restrict qualified pointers are const,
or merely nothing attempts to modify them during the scope of a
restrict qualified pointer, they keyword has no meaning at all.

It is all about telling the compiler when it can assume that the
pointed to object(s) will not be changed without its knowledge.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Mar 6 '06 #2

Jack Klein wrote:
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:
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;

int *temp = bp;


This should require a cast, I believe.


Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?

Mar 6 '06 #3
en******@yahoo. com wrote:
Jack Klein wrote:
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:

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;

int *temp = bp;


This should require a cast, I believe.

Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?

No it's a straight assignment. Nothing you do with i can change ci.
whereas assigning a const pointer to a non-const violates the
restriction because you can alter the value the pointer points to.

--
Ian Collins.
Mar 6 '06 #4

Ian Collins wrote:
en******@yahoo. com wrote:
Jack Klein wrote:
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:
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;

int *temp = bp;

This should require a cast, I believe.

Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?

No it's a straight assignment. Nothing you do with i can change ci.
whereas assigning a const pointer to a non-const violates the
restriction because you can alter the value the pointer points to.


Read the original example again. The type qualifier
modifies the type of the pointer, not the type of what
the pointer points to.

Mar 6 '06 #5

"Jack Klein" <ja*******@spam cop.net> wrote in message
news:h9******** *************** *********@4ax.c om...
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:
I'm trying to wrap my head around the wording but from what I think the
standard says:

1. [snip]

2. it doesn't support exactly overlapping memory, i.e.

void v3add(float * restrict a, float * restrict b)
{
a[0] += b[0];
a[1] += b[1];
a[2] += b[2];
}

float a[] = { 1, 2, 3 };
v3add(a, a);

is undefined.


The function itself is well defined, the call to the function is, I
suppose, technically undefined. Although there is no problem with
this actual use.
3. [snip]


Your second example is not really undefined because even though
modifying objects pointed to by 'a' also modifies objects pointed to
by 'b', there is no use of the value of any object pointed to by 'b'
after it is modified by the write through 'a'.


Trouble is, restrict gives the compiler unlimited licence to rearrange.
Just because the source as written doesn't access any object after it's
modified, even when there's aliasing, doesn't mean the compiler can't
introduce such an access.

Consider this reversal of your example:

void v3add(float * restrict a, float * restrict b)
{
float b0;
a[0] += b0 = b[0];
a[1] += b0;
a[2] += b0;
}

The compiler, relying on restrict, might decide to eliminate b0 by accessing
b[0] 3 times (well I didn't say it was a good compiler). Now, v3add(a, a)
breaks even though nothing is accessed after it's modified in the source as
written.

It seems the OP is right, aliasing restricted pointers is absolutely
dangerous. We can't anticipate all possible bright ideas that the compiler
might have and decide that the aliasing will survive all of them. If we
want the code compiled with the semantics as written, we have to avoid
restrict and stick to documenting the restrictions on overlaps.

--
RSH


Mar 6 '06 #6
en******@yahoo. com wrote:
Ian Collins wrote:
en******@yaho o.com wrote:
Jack Klein wrote:
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:

>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;
>
>int *temp = bp;

This should require a cast, I believe.
Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?


No it's a straight assignment. Nothing you do with i can change ci.
whereas assigning a const pointer to a non-const violates the
restriction because you can alter the value the pointer points to.

Read the original example again. The type qualifier
modifies the type of the pointer, not the type of what
the pointer points to.

Your are correct, but this doesn't invalidate the first part of the answer.

My understanding is the expression 'int *temp = bp;' is valid because
temp is a pointer based on bp. Please correct me if I'm wrong. I don't
see where a cast would be required.
--
Ian Collins.
Mar 6 '06 #7

Ian Collins wrote:
en******@yahoo. com wrote:
Ian Collins wrote:
en******@yaho o.com wrote:

Jack Klein wrote:
>On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
>wrote in comp.lang.c:
>
>
>
>>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;
>>
>>int *temp = bp;
>
>This should require a cast, I believe.
Do you also think the setting of i below requires a cast?

const int ci = 1;
int i = ci;

If not, can you explain how the two examples differ
with regard to type qualifiers?
No it's a straight assignment. Nothing you do with i can change ci.
whereas assigning a const pointer to a non-const violates the
restriction because you can alter the value the pointer points to.

Read the original example again. The type qualifier
modifies the type of the pointer, not the type of what
the pointer points to.

Your are correct, but this doesn't invalidate the first part of the answer.

My understanding is the expression 'int *temp = bp;' is valid because
temp is a pointer based on bp. Please correct me if I'm wrong. I don't
see where a cast would be required.


That's the point I was making. 'int *temp = bp;' does not
require a cast.

Mar 6 '06 #8
Jack Klein <ja*******@spam cop.net> wrote:
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:

FILE *fopen(const char * restrict filename, const char * restrict
mode);

FILE *f = fopen("foo.rt", "rt");

if the compiler transforms this to:

static const char str[] = "foo.rt";
FILE *f = fopen(str, str + 4);

the code becomes undefined.


No, the code above is well-defined. In fact, it is possible that a
compiler might generate this code itself, as merging string literals
is allowed by the standard and some compilers do it.

So what is the point in declaring parameters as restrict pointers
to const data?

Since the data may be const, the function presumably does not try to
modify it, therefore `restrict' seems to take effect neither in the
function definition (if there is any) nor as a requirement for the caller.

--
Stan Tobias
mailx `echo si***@FamOuS.Be dBuG.pAlS.INVALID | sed s/[[:upper:]]//g`
Mar 6 '06 #9
In article <47************ @individual.net >,
"S.Tobias" <si***@FamOuS.B edBuG.pAlS.INVA LID> wrote:
Jack Klein <ja*******@spam cop.net> wrote:
On 5 Mar 2006 17:30:37 -0800, "Me" <an************ *****@yahoo.com >
wrote in comp.lang.c:

FILE *fopen(const char * restrict filename, const char * restrict
mode);

FILE *f = fopen("foo.rt", "rt");

if the compiler transforms this to:

static const char str[] = "foo.rt";
FILE *f = fopen(str, str + 4);

the code becomes undefined.


No, the code above is well-defined. In fact, it is possible that a
compiler might generate this code itself, as merging string literals
is allowed by the standard and some compilers do it.

So what is the point in declaring parameters as restrict pointers
to const data?

Since the data may be const, the function presumably does not try to
modify it, therefore `restrict' seems to take effect neither in the
function definition (if there is any) nor as a requirement for the caller.


Just because you have a const pointer pointing to the data doesn't mean
it is const. All it means that you cannot modify the data through this
pointer without a cast, but it can be modified by other means.

Example:

static int x;
int f (const int* p)
{
if (*p == 0) ++x;
if (*p == 0) ++x;
return *p;
}

An optimising compiler might be tempted to produce code that doesn't
read *p three times, but instead translates it as if I had written:

static int x;
int f (const int* p)
{
int tmp = *p;
if (tmp == 0) x += 2;
return tmp;
}

But this would be wrong, because I could call this as

int y = f (&x);

If x happens to be zero before the call, then it must be incremented
only once and a value of 1 must be returned, so the compiler is forced
to produce slower code. If you write

int f (const int* restrict p)

then it is guaranteed by the programmer that nothing will modify *p
while the function is running. The programmer guarantees that he/she
doesn't pass &x when x is 0.
Mar 6 '06 #10

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

Similar topics

0
1486
by: Mohammad Khan | last post by:
------=_NextPart_000_005F_01C35137.8729F1B0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Is there any way to restrict UPDATE without a WHERE clause? Mohammad Khan Software Engineer
1
1423
by: hristov.milen | last post by:
Hi, Is there a way to restrict selecting from a table.. I have problem with one check, I have select and after this insert based on the select. If it happen in one time .. I can insert incorrect information. If I do lock table SOMETABLE read; it still select and return results normaly. I'm open for suggestions :)
1
1363
by: Dani | last post by:
Hi, I am using codeDom class to compile on fly some c# code. I want to restrinc to use some assembly, i don't know if assembly is the best word, i want to forbid to use class like System.IO.File or System.IO.Directory, how can i do it?? I thought i can do it parsing the code looking for the key word, but i think can be another...
2
1340
by: atif | last post by:
I hav a prob with the textfield i want to restrict this field so that only integer values should b entered e.g 0-9 n no english or special characters should b entered in the text field Posted Via Usenet.com Premium Usenet Newsgroup Services ---------------------------------------------------------- ** SPEED ** RETENTION ** COMPLETION **...
0
924
by: Agnes | last post by:
I had design a textbox which allow input 'date' only . I can restrict "English character" However, I don't know how to disallow the user input ' chinese characters' , Please help, and thanks a lot
21
6485
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
2036
by: plankton | last post by:
Hi all, I'm new to this group so please accept my apologies if this has already been covered! I have a site thats for my mates and myself to use from a chat room we all frequent and have been trying to install a forum for god knows how long now. I'm not really very good with html, sql and all that stuff as i've just
4
3788
by: Joshua Mostafa | last post by:
Hi there. I have a question regarding restrictions in an XML Schema definition. My XML contains a structure like this: <fruit-bowl> <fruit name="apple" /> <fruit name="pear" /> <fruit name="lychee" favourite="true" />
23
4804
by: raashid bhatt | last post by:
what is restrict keyword used for? eg int *restrict p;
0
7710
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...
0
7625
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...
0
7935
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. ...
0
8144
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7692
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...
0
6313
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...
1
5519
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...
0
3677
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
1
2128
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

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.