Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C++

Từ khóa restrict trong C

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ếu restrict int* p, thì trong phạm vi của p, 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 *z không thay đổi qua *x hoặc *y
  • Có thể cache *z trong 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ợ __restrict hoặ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ợ
C99restrict (chuẩn)
C++98/11/14/17/20Không chuẩn (dùng extension compiler)
GCC/Clang C++__restrict__
MSVC C++__restrict