G
gc
Hi,
What is the purpose of the restrict keyword?
gc
What is the purpose of the restrict keyword?
gc
Hi,
What is the purpose of the restrict keyword?
Andreas said:The data pointed to by a pointer declared with the restrict
qualifier may not be pointed to by any other pointer.
This allows for more effective optimization.
For example, the two pointers used as arguments to memcpy()
are declared with restrict, which simply means that
the two data areas may not overlap.
#include <stddef.h>> cat memcpy.c
> gcc -Wall -std=c99 -pedantic -O2 -c memcpy.c
Andreas said:[cut]gc said:What is the purpose of the restrict keyword?
For example, the two pointers used as arguments to memcpy()
are declared with restrict, which simply means that
the two data areas may not overlap.
Would you mind elaborating a little on this?
My memcpy doesn't use the *restrict* keyword:
Andreas said:I chose that example because that's the example that the
standard )or was it the rationale) uses. Later, the standard
indeed defines memcpy() as taking two restrict pointers. For
Unix-type systems that claims to be POSIX compatible, see also
the Single Unix Specification at
http://www.opengroup.org/onlinepubs/007904975/functions/memcpy.html
NAME
memcpy - copy bytes in memory
SYNOPSIS
#include <string.h>
void *memcpy(void *restrict s1, const void *restrict s2, size_t
n);
DESCRIPTION
The functionality described on this reference page
is aligned with the ISO C standard.
Any conflict between the requirements described here
and the ISO C standard is unintentional.
This volume of IEEE Std 1003.1-2001 defers to the ISO C standard.
The memcpy() function shall copy n bytes
from the object pointed to by s2 into the object pointed to by
s1. If copying takes place between objects that overlap,
the behavior is undefined.
This behavior is no different from the behavior described in
the old ANSI/ISO C89 standard and my Linux man page.
The restrict keyword appears to serve *no* useful function
in the above declaration of memcpy.
Which begs the question,
"What is the purpose of the restrict keyword?"
E. Robert Tisdale said:This behavior is no different from the behavior described in
the old ANSI/ISO C89 standard and my Linux man page.
The restrict keyword appears to serve *no* useful function
in the above declaration of memcpy.
Which begs the question,
"What is the purpose of the restrict keyword?"
E. Robert Tisdale said:NAME
memcpy - copy bytes in memory
SYNOPSIS
#include <string.h>
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
DESCRIPTION
The functionality described on this reference page
is aligned with the ISO C standard.
Any conflict between the requirements described here
and the ISO C standard is unintentional.
This volume of IEEE Std 1003.1-2001 defers to the ISO C standard.
The memcpy() function shall copy n bytes
from the object pointed to by s2 into the object pointed to by s1.
If copying takes place between objects that overlap,
the behavior is undefined.
This behavior is no different from the behavior described in
the old ANSI/ISO C89 standard and my Linux man page.
The restrict keyword appears to serve *no* useful function
in the above declaration of memcpy.
Which begs the question,
"What is the purpose of the restrict keyword?"
Mark said:It means that if the memcpy routine in the library is written in C the
compiler is free to make use of the fact the pointers point to different
objects in it's optimization. This increases the potential for an
implementation to write the libraries in C whilst still having them
efficient.
It makes it easier if the compiler writer wants to make the compiler
generate diagnostics if at compile time it is possible to determine
that the two pointer are in fact the same without having to treat memcpy
as a special case. Not that the compiler writer is obliged to generate a
diagnostic for this, but it is permitted.
It also means that the prototype provides more information to anyone
reading it than would otherwise be the case.
Even prototypes for library functions should be designed to indicate as
much about the use of parameters as is practical, even if there is no
obvious benefit other than making it clearer to a human reader.
Mark said:It means that if the memcpy routine in the library is written in C the
compiler is free to make use of the fact the pointers point to different
objects in it's optimization. This increases the potential for an
implementation to write the libraries in C whilst still having them
efficient.
It makes it easier if the compiler writer wants to make the compiler
generate diagnostics if at compile time it is possible to determine
that the two pointer are in fact the same without having to treat memcpy
as a special case. Not that the compiler writer is obliged to generate a
diagnostic for this, but it is permitted.
It also means that the prototype provides more information to anyone
reading it than would otherwise be the case.
Even prototypes for library functions should be designed to indicate as
much about the use of parameters as is practical, even if there is no
obvious benefit other than making it clearer to a human reader.
Evidently, you are saying that a C 99 compiler is permitted
to do a better job of optimizing this definition:
void *memcpy(void *restrict s1,
const void *restrict s2, size_t n) {
for (int j = 0; j < n; ++j)
((char*)s1)[j] = ((char*)s2)[j];
return s1;
}
than it is allowed to do for this definition:
void *memcpy(void *s1,
const void *s2, size_t n) {
for (int j = 0; j < n; ++j)
((char*)s1)[j] = ((char*)s2)[j];
return s1;
}
Further, you appear to be saying that
the appearance of the restrict keyword in the
declaration of memcpy (what you call the prototype)
serves no purpose except for documentation
as the ANSI/ISO C99 standard does *not*
require the compiler to detect any aliases
and issue a diagnostic for it when memcpy is invoked.
NAME
memcpy - copy bytes in memory
SYNOPSIS
#include <string.h>
void *memcpy(void *restrict s1, const void *restrict s2, size_t n);
DESCRIPTION
The functionality described on this reference page
is aligned with the ISO C standard.
Any conflict between the requirements described here
and the ISO C standard is unintentional.
This volume of IEEE Std 1003.1-2001 defers to the ISO C standard.
The memcpy() function shall copy n bytes
from the object pointed to by s2 into the object pointed to by s1.
If copying takes place between objects that overlap,
the behavior is undefined.
This behavior is no different from the behavior described in
the old ANSI/ISO C89 standard and my Linux man page.
The restrict keyword appears to serve *no* useful function
in the above declaration of memcpy.
Which begs the question,
"What is the purpose of the restrict keyword?"
The memcpy() function shall copy n bytes
from the object pointed to by s2 into the object pointed to by s1.
If copying takes place between objects that overlap,
the behavior is undefined.
Jack Klein said:On Wed, 01 Oct 2003 12:47:43 -0700, "E. Robert Tisdale"
Because the "restrict" keyword replaces the entire paragraph:
E. Robert Tisdale said:Andreas said:For example, the two pointers used as arguments to memcpy()
are declared with restrict, which simply means that
the two data areas may not overlap.
Would you mind elaborating a little on this?
My memcpy doesn't use the *restrict* keyword: [snip]
In the example above, &a[12] is an alias for part of array a
but my compiler doesn't complain. Is this a bug in my compiler?
Jeremy said:It is precisely because aliasing cannot be easily and reliably
detected that "restrict" is needed: it allows the programmer to
provide extra information that the compiler cannot (and ought not to)
deduce unaided. (It also has the secondary purpose of documentation
for human readers, of course).
?No.
The restrict keyword does *not* provide any extra information
to the compiler.
It simple allows the programmer to *lie* to the C compiler.
It tells the C compiler to *assume* that
source and destination arrays are disjoint
even though there is no way for either the programmer
or the C compiler to ensure that
source and destination arrays do *not* overlap.
Alan said:?
I agree that I don't expect the compiler to know, but I don't have a
problem knowing when source and destinations buffers overlap.
Really!
void *memcpy(void *restrict dest,
const void *restrict src, size_t n) {
// Please show us how you you would know
// when dest and src overlap.
return dest;
}
Thanks!Andreas Kahari said:The data pointed to by a pointer declared with the restrict
qualifier may not be pointed to by any other pointer. This
allows for more effective optimization.
E. Robert Tisdale said:No.
The restrict keyword does *not* provide any extra information
to the compiler.
It simple allows the programmer to *lie* to the C compiler.
It tells the C compiler to *assume* that
source and destination arrays are disjoint
even though there is no way for either the programmer
or the C compiler to ensure that
source and destination arrays do *not* overlap.
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.