restrict là từ khóa chuẩn C99 dùng cho khai báo con trỏ, thông báo cho trình biên dịch rằng: con trỏ này là cách duy nhất truy cập vào đối tượng nó trỏ đến trong phạm vi sống của nó. Giúp compiler tối ưu hóa mã tốt hơn.
Cú pháp
void func(int* restrict ptr);
// hoặc
void func(int* __restrict ptr); // GCC/Clang extension trước C99
Ý nghĩa
Nếurestrict int* p, thì trong phạm vi củap, không có con trỏ nào khác (kể cả tên biến gốc) truy cập vào cùng vùng nhớ đó.
Ví dụ minh họa
#include <stdio.h>
// z được khai báo restrict -> compiler biết *z không alias với *x hay *y
void my_function(int* x, int* y, int* restrict z) {
*x += *z;
*y += *z;
}
int main() {
int x = 10, y = 20, z = 30;
my_function(&x, &y, &z);
printf("%d %d %d\n", x, y, z); // 40 50 30
return 0;
}
Kết quả
40 50 30
Tại sao restrict giúp tối ưu?
Nếu không có restrict, compiler phải giả định x, y, z có thể trỏ đến cùng địa chỉ (aliasing). Với restrict trên z:
- Compiler biết
*zkhông thay đổi qua*xhoặc*y - Có thể cache
*ztrong register - Có thể sắp xếp lại lệnh (reorder) an toàn
- Vectorization (SIMD) dễ dàng hơn
Vi phạm restrict → Undefined Behavior
void bad(int* restrict a, int* restrict b) {
*a = 1;
*b = 2;
}
int main() {
int x = 0;
bad(&x, &x); // UNDEFINED BEHAVIOR: a và b trỏ cùng địa chỉ!
}
Restrict với các kiểu khác
// Con trỏ đến const
void func(const int* restrict p);
// Con trỏ restrict đến const
void func(int* const restrict p); // p là const, *p có restrict
// Struct/Union
struct S { int* restrict p; };
// Tham chiếu C++ không có restrict (dùng __restrict__ extension)
Lưu ý
- Chỉ có trong C99, không có trong C++ chuẩn (nhưng GCC/Clang/MSVC hỗ trợ
__restricthoặc__restrict__) - Không thêm chức năng mới, chỉ cho phép tối ưu hóa
- Dùng cho tham số hàm, biến cục bộ con trỏ
- Vi phạm = Undefined Behavior (chương trình có thể chạy sai silent)
So sánh với C++
| Ngôn ngữ | Hỗ trợ |
|---|---|
| C99 | restrict (chuẩn) |
| C++98/11/14/17/20 | Không chuẩn (dùng extension compiler) |
| GCC/Clang C++ | __restrict__ |
| MSVC C++ | __restrict |