What is restrict in C?
The restrict keyword was introduced in C99 as a type qualifier for pointers. It tells the compiler that the pointer is the only means by which the memory it points to will be accessed for the duration of its lifetime.
This allows the compiler to safely optimize code by assuming no aliasing — meaning no other pointer accesses the same memory.
Syntax Example:
void copy(int *restrict dst, const int *restrict src, size_t n);
Benefits:
- Enables more aggressive compiler optimizations
- Improves performance in tight loops and memory-heavy operations
- Clarifies developer intent about pointer usage
Without restrict:
void copy(int *dst, const int *src, size_t n);
Without restrict, the compiler must assume that dst and src might point to overlapping memory, reducing the scope of safe optimizations.
Important Notes:
restrictis only valid in C99 and later- Only applies to pointers
- Misusing it causes undefined behavior
Does C++ Have restrict?
C++ does not include restrict in the standard language. However, some workarounds exist.
1. Compiler Extensions
Most major compilers support non-standard equivalents like:
void foo(int* __restrict__ a, int* __restrict__ b);
- GCC/Clang:
__restrict__ - MSVC:
__restrict
Note: These are non-portable.
2. Better Semantics with Modern C++
Modern C++ promotes safer and clearer alternatives, such as:
- Passing references instead of raw pointers
- Using
std::span(C++20) to express memory ranges explicitly
void add(std::span<int> dst, std::span<const int> src);
While this doesn’t guarantee no aliasing at the compiler level, it makes intentions clearer and helps avoid common aliasing issues in practice.
Summary Table
| Feature | C | C++ |
|---|---|---|
restrict support |
Standard (C99+) | Not in standard |
| Optimization boost | Yes | Yes (via extensions) |
| Safer alternatives | No | std::span, references |
Conclusion
Use restrict in C when performance matters and aliasing can be safely ruled out. In C++, favor cleaner memory semantics and modern language features — or, where necessary, use compiler-specific extensions with caution.
C/C++ Programming
- Understanding std::transform_reduce in Modern C++
- Implement a Lock Acquire and Release in C++
- Detecting Compile-time vs Runtime in C++: if consteval vs std::is_constant_evaluated()
- C++ Forward References: The Key to Perfect Forwarding
- Understanding dynamic_cast in C++: Safe Downcasting Explained
- C vs C++: Understanding the restrict Keyword and its Role in Optimization
- C++ Lvalue, Rvalue and Rvalue References
- C++ assert vs static_assert
- Why auto_ptr is Deprecated in C++?
- C++ What is the consteval? How is it different to const and constexpr?
- Tutorial on C++ std::move (Transfer Ownership)
- const vs constexpr in C++
- Tutorial on C++ Ranges
- Tutorial on C++ Smart Pointers
- Tutorial on C++ Future, Async and Promise
- The Memory Manager in C/C++: Heap vs Stack
- The String Memory Comparision Function memcmp() in C/C++
- Modern C++ Language Features
- Comparisions of push_back() and emplace_back() in C++ std::vector
- C++ Coding Reference: is_sorted_until() and is_sorted()
- C++ Coding Reference: iota() Setting Incrementing Values to Arrays or Vectors
- C++ Coding Reference: next_permutation() and prev_permutation()
- C++ Coding Reference: count() and count_if()
- C++ Code Reference: std::accumulate() and Examples
- C++ Coding Reference: sort() and stable_sort()
- The Next Permutation Algorithm in C++ std::next_permutation()
–EOF (The Ultimate Computing & Technology Blog) —
Last Post: ROS Topics, Services, and Actions Explained with Clear Examples
Next Post: Teaching Kids Programming - Fibonacci Numbers in (Generate Binary Strings Without Adjacent Zeros)