{{short description|Keyword in C (programming language)}} {{Lowercase title}} {{About|the C programming language keyword||Restriction (disambiguation)}}
In the C programming language, <code>'''restrict'''</code> is a type qualifier that can be applied to a pointer to hint to the compiler that for the lifetime of that pointer, no other pointer will be used to access the same pointed-to object. This limits the effects of pointer aliasing, which can allow the compiler to make optimizations (such as vectorization) that would not otherwise be possible. Undefined behaviour results if the declaration of intent is not followed and the object is accessed by an independent pointer.
The <code>restrict</code> keyword was introduced by the C99 standard. Despite C++ supporting most features of C, <code>restrict</code> is not included in standard C++.
== 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:
<syntaxhighlight lang="c"> void updatePtrs(size_t* ptrA, size_t* ptrB, size_t* val) { *ptrA += *val; *ptrB += *val; } </syntaxhighlight>
In the above code, the pointers <code>ptrA</code>, <code>ptrB</code>, and <code>val</code> ''might'' refer to the same memory location, so the compiler may generate less optimal code: <syntaxhighlight lang="nasm"> ; Hypothetical RISC Machine. ldr r12, [val] ; Load memory at val to r12. ldr r3, [ptrA] ; Load memory at ptrA to r3. add r3, r3, r12 ; Perform addition: r3 = r3 + r12. str r3, [ptrA] ; Store r3 to memory location ptrA, updating the value. ldr r3, [ptrB] ; 'load' may have to wait until preceding 'store' completes. ldr r12, [val] ; Have to load a second time to ensure consistency. add r3, r3, r12 str r3, [ptrB] </syntaxhighlight>
However, if the <code>restrict</code> keyword is used and the above function is declared as
<syntaxhighlight lang="c"> void updatePtrs(size_t* restrict ptrA, size_t* restrict ptrB, size_t* restrict val); </syntaxhighlight>
then the compiler is allowed to ''assume'' that <code>ptrA</code>, <code>ptrB</code>, and <code>val</code> 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.
<syntaxhighlight lang="nasm"> ldr r12, [val] ; Note that val is now only loaded once. ldr r3, [ptrA] ; Also, all 'load's in the beginning ... ldr r4, [ptrB] add r3, r3, r12 add r4, r4, r12 str r3, [ptrA] ; ... all 'store's in the end. str r4, [ptrB] </syntaxhighlight>
The above assembly code is shorter because <code>val</code> is loaded only once. Without <code>val</code> being restricted, its possible for <code>ptrA</code> to alias with it. This would result in <code>val</code> changing on the first addition, when <code>ptrA</code> 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 <code>store</code> operations are all taking place after the <code>load</code> operations, ensuring that the processor won't have to block in the middle of the code to wait until the <code>store</code> operations are complete. This reordering is enabled because pointers <code>ptrA</code> and <code>ptrB</code> were marked with <code>restrict</code>, which ensures that the user won't call the function with these pointers aliased, expecting <code>val</code> 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. 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 <code>restrict</code>, but many compilers have equivalents that usually work in both C++ and C, such as the GCC's and Clang's <code>__restrict__</code>, and Visual C++'s <code>__declspec(restrict)</code>. In addition, <code>__restrict</code> 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, {{code|__restrict}} and {{code|__restrict__}} mean exactly the same as their C counterpart. Extensions include allowing them to be applied to reference types and {{code|this}}.<ref>{{cite web |website=Using the GNU Compiler Collection (GCC)|title= Restricted Pointers |url=https://gcc.gnu.org/onlinedocs/gcc/Restricted-Pointers.html}}</ref> * In Visual C++, multiple no-alias qualifiers are provided: *# {{code|__declspec(restrict)}} applies to the function declaration and hints that the ''returned'' pointer is not aliased. *# {{code|__restrict}} is used in the same place as {{code|restrict}}, but the no-alias hint does not propagate as in {{code|restrict}}. It is also extended for union types.
==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 {{code|restrict}}.<ref>{{cite web |title=Warning Options: -Wrestrict |url=https://gcc.gnu.org/onlinedocs/gcc-8.1.0/gcc/Warning-Options.html#index-Wrestrict |website=GCC |accessdate=19 November 2019}}</ref> The CERT C Coding Standard considers misuse of {{code|restrict}} 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.<ref>{{cite web |title=EXP43-C. Avoid undefined behavior when using restrict-qualified pointers |url=https://wiki.sei.cmu.edu/confluence/display/c/EXP43-C.+Avoid+undefined+behavior+when+using+restrict-qualified+pointers |website=SEI CERT C Coding Standard |accessdate=19 November 2019}}</ref>
==References== {{reflist}} *{{cite web |url=http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf |title=ISO/IEC 9899:TC2 Committee Draft |publisher=ISO |date=May 6, 2005 |accessdate=2008-12-22 |pages=108–112 }}
==External links==
* [https://cellperformance.beyond3d.com/articles/2006/05/demystifying-the-restrict-keyword.html 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}} * [https://www.lysator.liu.se/c/restrict.html Restricted Pointers in C]: the original rationale behind the definition
Category:C (programming language)