In the
C programming language
C (''pronounced'' '' – like the letter c'') is a general-purpose programming language. It was created in the 1970s by Dennis Ritchie and remains very widely used and influential. By design, C's features cleanly reflect the capabilities of ...
,
restrict
is a
keyword, introduced by the
C99 standard, that can be used in
pointer declarations. By adding this
type qualifier, a programmer hints to the
compiler
In computing, a compiler is a computer program that Translator (computing), translates computer code written in one programming language (the ''source'' language) into another language (the ''target'' language). The name "compiler" is primaril ...
that for the lifetime of the pointer, no other pointer will be used to access the object to which it points. This allows the compiler to make optimizations (for example, vectorization) that would not otherwise have been possible.
restrict
limits the effects of
pointer aliasing, aiding
optimizations. If the declaration of intent is not followed and the object is accessed by an independent pointer, this will result in
undefined behavior
In computer programming, a program exhibits undefined behavior (UB) when it contains, or is executing code for which its programming language specification does not mandate any specific requirements. This is different from unspecified behavior, ...
.
Optimization
If the compiler knows that there is only one pointer to a memory block, it can produce better optimized code. For instance, in a function which adds a value to both its arguments:
void updatePtrs(size_t *ptrA, size_t *ptrB, size_t *val)
In the above code, the pointers
ptrA
,
ptrB
, and
val
''might'' refer to the
same memory location, so the compiler may generate less optimal code:
; Hypothetical RISC Machine.
ldr r12, al ; Load memory at val to r12.
ldr r3, trA Tra or TRA may refer to:
Biology
* TRA (gene), in humans encodes the protein T-cell receptor alpha locus
* Tra (gene), in ''Drosophila melanogaster'' encodes the protein female-specific protein transformer
* Tra gene, a transfer gene
* Triple rel ...
; Load memory at ptrA to r3.
add r3, r3, r12 ; Perform addition: r3 = r3 + r12.
str r3, trA Tra or TRA may refer to:
Biology
* TRA (gene), in humans encodes the protein T-cell receptor alpha locus
* Tra (gene), in ''Drosophila melanogaster'' encodes the protein female-specific protein transformer
* Tra gene, a transfer gene
* Triple rel ...
; Store r3 to memory location ptrA, updating the value.
ldr r3, trB ; 'load' may have to wait until preceding 'store' completes.
ldr r12, al ; Have to load a second time to ensure consistency.
add r3, r3, r12
str r3, trB
However, if the
restrict
keyword is used and the above function is declared as
void updatePtrs(size_t *restrict ptrA, size_t *restrict ptrB, size_t *restrict val);
then the compiler is allowed to ''assume'' that
ptrA
,
ptrB
, and
val
point to different locations and updating the memory location referenced by one pointer will not affect the memory locations referenced by the other pointers. The programmer, not the compiler, is responsible for ensuring that the pointers do not point to identical locations. The compiler can e.g. rearrange the code, first loading all memory locations, then performing the operations before committing the results back to memory.
ldr r12, al ; Note that val is now only loaded once.
ldr r3, trA Tra or TRA may refer to:
Biology
* TRA (gene), in humans encodes the protein T-cell receptor alpha locus
* Tra (gene), in ''Drosophila melanogaster'' encodes the protein female-specific protein transformer
* Tra gene, a transfer gene
* Triple rel ...
; Also, all 'load's in the beginning ...
ldr r4, trBadd r3, r3, r12
add r4, r4, r12
str r3, trA Tra or TRA may refer to:
Biology
* TRA (gene), in humans encodes the protein T-cell receptor alpha locus
* Tra (gene), in ''Drosophila melanogaster'' encodes the protein female-specific protein transformer
* Tra gene, a transfer gene
* Triple rel ...
; ... all 'store's in the end.
str r4, trB
The above assembly code is shorter because
val
is loaded only once. Without
val
being restricted, its possible for
ptrA
to alias with it. This would result in
val
changing on the first addition, when
ptrA
is updated, and thus needing to be reloaded. The above assembly code is also faster, since the compiler can rearrange the code more freely. In the second version of the above example, the
store
operations are all taking place after the
load
operations, ensuring that the processor won't have to block in the middle of the code to wait until the
store
operations are complete. This reordering is enabled because pointers
ptrA
and
ptrB
were marked with
restrict
, which ensures that the user won't call the function with these pointers aliased, expecting
val
to be added twice to the integer they both refer to.
Note that the real generated code may have different behaviors. depending on how the compiler uses the additional information. The benefit with the above mini-example may be small, and in real-life cases large loops doing heavy memory access tends to be what is really helped by restrict.
As mentioned above, how incorrect code behaves is
undefined
Undefined may refer to:
Mathematics
*Undefined (mathematics), with several related meanings
**Indeterminate form, in calculus
Computing
*Undefined behavior, computer code whose behavior is not specified under certain conditions
*Undefined valu ...
. The compiler only ensures the generated code works properly if the code follows the declaration of intent, and the optimizations it enables will likely cause the code to behave incorrectly when the pointers are aliased. Compilers may detect and warn in some cases where pointers are aliased, but are not required to.
Support by C++ compilers
C++ does not have standard support for
restrict
, but many compilers have equivalents that usually work in both C++ and C, such as the
GCC's and
Clang
Clang () is a compiler front end for the programming languages C, C++, Objective-C, Objective-C++, and the software frameworks OpenMP, OpenCL, RenderScript, CUDA, SYCL, and HIP. It acts as a drop-in replacement for the GNU Compiler ...
's
__restrict__
, and
Visual C++
Microsoft Visual C++ (MSVC) is a compiler for the C, C++, C++/CLI and C++/CX programming languages by Microsoft. MSVC is proprietary software; it was originally a standalone product but later became a part of Visual Studio and made available ...
's
__declspec(restrict)
. In addition,
__restrict
is supported by those three compilers. The exact interpretation of these alternative keywords vary by the compiler:
* In Unix-style compilers such as GCC and Clang, and mean exactly the same as their C counterpart. Extensions include allowing them to be applied to reference types and .
* In Visual C++, multiple no-alias qualifiers are provided:
*# applies to the function declaration and hints that the ''returned'' pointer is not aliased.
*# is used in the same place as , but the no-alias hint does not propagate as in . It is also extended for
union type
Union commonly refers to:
* Trade union, an organization of workers
* Union (set theory), in mathematics, a fundamental operation on sets
Union may also refer to:
Arts and entertainment Music
* Union (band), an American rock group
** ''Unio ...
s.
Compiler warnings
To help prevent incorrect code, some compilers and other tools try to detect when overlapping arguments have been passed to functions with parameters marked . The
CERT C Coding Standard considers misuse of and library functions marked with it (EXP43-C) a probable source of software bugs, although as of November 2019 no vulnerabilities are known to have been caused by this.
References
*
External links
Demystifying The Restrict Keyword explanation and examples of use
* {{cite web, url=https://www.oracle.com/technetwork/server-storage/solaris10/cc-restrict-139391.html, title=How to Use the restrict Qualifier in C, last=Walls, first=Douglas , publisher=Oracle™, accessdate=2012-11-21
the original rationale behind the definition
C (programming language)