Restringir

La versión actual de la página aún no ha sido revisada por colaboradores experimentados y puede diferir significativamente de la versión revisada el 22 de marzo de 2021; las comprobaciones requieren 22 ediciones .

restrict  es una palabra clave en el lenguaje de programación C introducido por el estándar C99 y utilizado en declaraciones de puntero .

char * restringir p1 ; int ** restringir p2 ; float * restringir p3 , * restringir p4 ;

La palabra clave restrictpermite al programador decirle al compilador que el puntero que se declara se dirige a una región de la memoria a la que no hace referencia ningún otro puntero. La garantía de que más de un puntero no hará referencia a un área de memoria la da el programador. En este caso, el compilador de optimización puede generar un código más eficiente (vea un ejemplo a continuación).

El estándar no define el uso de la palabra clave restrictcuando se declaran objetos que no sean punteros .

Usando la palabra clave, un programa escrito en C "inteligente" puede ser tan rápido como un programa escrito en Fortranrestrict "estúpido" [1] .

No hay palabra clave en el lenguaje C++restrict (no se describe en el estándar), pero los desarrolladores de varios compiladores de C++ han agregado palabras clave que tienen un propósito similar, por ejemplo:

Ejemplo de optimización

El compilador puede generar menos código si sabe que solo un puntero se dirige a un bloque de memoria. Considere un ejemplo. Se define la siguiente función:

void actualizarPtrs ( tamaño_t * ptrA , tamaño_t * ptrB , tamaño_t * valor ) { * ptrA += * val ; * ptrB += * valor ; }

Punteros ptrAy pueden hacer referencia ptrBal valmismo bloque de memoria.

Para esta función, el compilador generará algo como el siguiente código:

carga R1 * val ; leer el valor de la memoria en el puntero val carga R2 * ptrA ; lee el valor de la memoria en el puntero ptrA agrega R2 += R1 ; realizar el conjunto de sumas R2 * ptrA ; escribir el resultado en la memoria en el puntero ptrA ; similar para carga ptrB R1 * val ; leyendo por val por segunda vez cargar R2 * ptrB sumar R2 += R1 establecer R2 * ptrB

Tenga en cuenta que el valor del puntero se vallee de la memoria dos veces. Esto se debe a que el puntero ptrApuede hacer referencia al mismo bloque de memoria que val, lo que significa que el valor valpuede cambiar cuando se escribe en el puntero ptrA.

Al usar la palabra clave restrict, la definición de la función sería:

void actualizarPtrs ( size_t * restringir ptrA , size_t * restringir ptrB , size_t * valor restringido ) { * ptrA += * val ; * ptrB += * valor ; }

La palabra clave restrictle dice al compilador que los punteros ptrA, ptrBy valnunca se dirigen al mismo bloque de memoria. Esto está garantizado por el programador.

En este caso, el compilador generará algo como el siguiente código:

carga R1 * valor cargar R2 * ptrA agregar R2 += R1 establecer R2 * ptrA ; carga R1 ← *val ; perdido cargar R2 * ptrB sumar R2 += R1 establecer R2 * ptrB

Tenga en cuenta que el código se ha acortado debido al hecho de que el valor valse lee de la memoria solo una vez.

Ejemplos de comportamiento indefinido

Un puntero con un calificador de tipo restricta un puntero con un calificador de tipo restrictsolo se puede definir en un bloque anidado. Ejemplo:

estructura T { int i ; }; estructura T var_1 ; int principal () { estructura T * restringir var_2 = & var_1 ; int * restringir var_3 = & var_2 -> i ; // comportamiento indefinido { int * restringir var_4 = & var_2 -> i ; // válido } devolver 0 ; }

Definir un puntero var_3 es un comportamiento indefinido porque var_3está en el mismo bloque que var_2. La definición var_4está en un bloque anidado y es válida.

__restrict para métodos en C++

La palabra clave para una __restrictestructura o método de clase de C++ indica que el puntero es de tipo " ". Ejemplo: thisT * __restrict const

estructura T { método vacío () __restrict {} };

Literatura

Véase también

Notas

  1. Ulrich Drepper . Memoria. parte 5 Lo que todo programador debe saber sobre la memoria . Revista electrónica lwn.net (23 de octubre de 2007). - Sin la palabra clave, el compilador considera que los punteros pueden apuntar al mismo bloque de memoria y genera un código no óptimo. Esta es una de las razones por las que Fortran todavía se usa para cálculos numéricos (lo que facilita la escritura de código rápido). En teoría, la introducción de C99 debería resolver este problema. Consultado el 5 de diciembre de 2014. Archivado desde el original el 30 de marzo de 2015.restrictrestrict
  2. gnu.org Restricción de alias de puntero Archivado el 6 de agosto de 2016 en Wayback Machine  . Documentación de CCG .