restrict is a keyword in the C programming language introduced by the C99 standard and used in pointer declarations.
char * restrict p1 ;
int ** restrict p2 ;
float * restrict p3 , * restrict p4 ;
The restrict keyword allows the programmer to tell the compiler that the declared pointer points to a block of memory that no other pointer points to. The guarantee that more than one pointer will not point to one memory block is given by the programmer. At the same time, the optimizing compiler can generate more efficient code (see the example below).
The use of the restrict keyword when declaring other objects (not pointers) is not defined by the standard.
Using the restrict keyword, a program written in smart C can be compared in speed to a program written in stupid Fortran [1] .
There is no restrict keyword in C ++ (not described in the standard), but developers of different C ++ compilers have added similar keywords for their intended purpose, for example:
__restrictand__restrict__for the GNU Compiler Collection [2] ;__restrictand__declspec(restrict)in Visual C ++ ;__restrict__at Clang .
Content
Optimization Example
The compiler can create less code if it knows that only one pointer points to one block of memory. Consider an example. The following function is defined:
void updatePtrs (
size_t * ptrA ,
size_t * ptrB ,
size_t * val
) {
* ptrA + = * val ;
* ptrB + = * val ;
}
Pointers ptrA , ptrB and val can point to the same memory block.
For this function, the compiler will generate approximately the following code:
; read value from memory at val pointer
load R1 ← * val
; read ptrA value from memory
load R2 ← * ptrA
; perform addition
add R2 + = R1
; write the result to memory using the ptrA pointer
set R2 → * ptrA
; similar for ptrB
load R1 ← * val ; read by val a second time
load R2 ← * ptrB
add R2 + = R1
set R2 → * ptrB
Note that the value at the pointer val read from memory twice. This is due to the fact that the ptrA pointer can point to the same memory block as val , that is, the value of val can change when the value is written using the ptrA pointer.
When using the restrict keyword, the function definition will be as follows:
void updatePtrs (
size_t * restrict ptrA ,
size_t * restrict ptrB ,
size_t * restrict val
) {
* ptrA + = * val ;
* ptrB + = * val ;
}
The restrict keyword tells the compiler that the pointers ptrA , ptrB and val never point to the same memory block. This is guaranteed by the programmer.
In this case, the compiler will generate approximately the following code:
load R1 ← * val
load R2 ← * ptrA
add R2 + = R1
set R2 → * ptrA
; load R1 ← * val; missing
load R2 ← * ptrB
add R2 + = R1
set R2 → * ptrB
Note that the code has become shorter because val is read from memory only once.
Examples of Undefined Behavior
A pointer with a restrict modifier to a pointer with a restrict modifier can only be defined in a nested block. Example:
struct T { int i ; };
struct T var_1 ;
int main () {
struct T * restrict var_2 = & var_1 ;
int * restrict var_3 = & var_2 -> i ; // undefined behavior
{
int * restrict var_4 = & var_2 -> i ; // valid
}
return 0 ;
}
The definition of the var_3 pointer is undefined behavior , since var_3 is in the same block as var_2 . The definition of var_4 is in a nested block and is valid.
__restrict for methods in C ++
The __restrict for a structure method or C ++ class means that the this pointer is of type “ T * __restrict const ”. Example:
struct T {
void method () __restrict {}
};
Literature
- Draft of ISO / IEC 9899: TC2. Programming language C (Russian) : journal. - ISO , 2005. - May 6. - S. 108-112 .
See also
- Demystifying the restrict keyword . Explanation and examples of use.
- Walls, Douglas Use of the restrict keyword in C (English) . Oracle ™ Date of treatment November 21, 2012.
- Restricted pointers in C The reasons for the introduction.
Notes
- ↑ Ulrich Drepper . Memory. Part 5 . What every programmer should know about memory . The electronic magazine lwn.net (October 23, 2007). - Without the
restrictkeyword, the compiler believes that pointers can point to the same memory block, and generates not optimal code. This is one of the reasons Fortran is still used for numerical calculations (it makes writing faster code easier). Theoretically, the introduction ofrestrictin C99 should solve this problem. - ↑ gnu.org Restricting pointer aliasing . Gcc documentation.