La palabra clave restrict es un especificador para punteros introducido en el estándar C99. Informa al compilador que el puntero es la única forma de acceder al objeto de memoria dentro del ámbito del puntero. Esto ayuda considerablemente al optimizador a crear un código de máquina más eficiente, especialmente al trabajar con grandes búferes.
Por ejemplo:
void vector_add(int * restrict a, int * restrict b, int * restrict c, size_t n) { for (size_t i = 0; i < n; ++i) c[i] = a[i] + b[i]; }
Aquí se supone que los arreglos a, b y c no se superponen. Violación de este requisito conduce a un comportamiento indefinido y a errores difíciles de rastrear.
Se recomienda el uso de restrict solo cuando esté seguro de que no hay otros punteros o caminos colaterales que apunten a la misma memoria.
¿Puede el mismo valor de memoria ser visible simultáneamente a través de dos punteros restrict?
Respuesta:
No, esto llevará a un comportamiento indefinido. No hay garantía de que el compilador considere los cambios realizados a través del segundo puntero. Un ejemplo de código críticamente incorrecto:
void f(int * restrict x, int * restrict y) { x[0] = 1; y[0] = 2; } int main() { int v; f(&v, &v); // Violación de la condición restrict }
Historia
En el núcleo de cálculo financiero, se optimizaron arreglos con la adición de restrict, pero no se tuvo en cuenta que los arreglos podrían superponerse según los requisitos de parte de la lógica de negocio. Esto llevó a un cálculo incorrecto del balance en el uso indebido.
Historia
El método de multiplicación por lotes de matrices se aceleró después de aplicar restrict, pero en una de las iteraciones, el arreglo de resultados se cruzó con uno de los arreglos de entrada: la respuesta se volvía impredecible, el error solo se detectaba mediante pruebas de carga.
Historia
En una de las funciones de procesamiento de imágenes, dos punteros a trozos del mismo búfer fueron accidentalmente declarados con restrict. Después de la actualización del compilador y su optimizador, el resultado del procesamiento de imágenes se volvió drásticamente distorsionado: la razón era que el compilador comenzaba a reutilizar el caché activamente e ignoraba las modificaciones.