__attribute__((const)) vs__attribute__((puro)) en GNU C
gcc attributes (3)
De la documentación para el compilador ARM (que se basa en gcc):
__attribute__((pure))
atributo de función
Muchas funciones no tienen efectos, excepto devolver un valor, y su valor de retorno depende solo de los parámetros y las variables globales. Las funciones de este tipo pueden estar sujetas a análisis de flujo de datos y podrían eliminarse.
__attribute__((const))
atributo de función
Muchas funciones examinan solo los argumentos que se les pasan y no tienen efectos, excepto el valor de retorno. Esta es una clase mucho más estricta que__attribute__((pure))
, porque una función no tiene permiso para leer la memoria global. Si se sabe que una función opera solo en sus argumentos, entonces puede estar sujeta a la eliminación de subexpresiones y optimizaciones de bucle comunes.
Entonces, TL; DR:
__attribute__((const))
es lo mismo que
__attribute__((pure))
pero sin ningún acceso a las variables globales.
¿Cuál es la diferencia entre
__attribute__((const))
y
__attribute__((pure))
en GNU C?
__attribute__((const)) int f() {
/* ... */
return 4;
}
vs
__attribute__((pure)) int f() {
/* ... */
return 4;
}
La diferencia se explica en los
manuales del CCG
.
Más notablemente, una función
const
solo puede usar los argumentos pasados y no cualquier memoria, mientras que una función
pure
puede acceder a la memoria, bajo restricciones:
El atributo puro prohíbe que una función modifique el estado del programa que es observable por otros medios que no sean la inspección del valor de retorno de la función. Sin embargo, las funciones declaradas con el atributo puro pueden leer de forma segura cualquier objeto no volátil y modificar el valor de los objetos de una manera que no afecte su valor de retorno o el estado observable del programa.
El
__attribute__ ((pure))
significa que la función no tiene efectos secundarios y el valor devuelto depende de los argumentos y del estado de las variables globales.
Por lo tanto, es seguro para el optimizador eludir algunas llamadas, si los argumentos son los mismos, y la
persona que llama no hizo nada para cambiar el estado de los globales entre las llamadas
.
El
__attribute__ ((const))
significa que el valor de retorno es únicamente una función de los argumentos, y
si alguno de los argumentos son punteros, entonces los punteros
no deben ser desreferenciados
.
Una función
const
siempre es
pure
.
Ejemplos de funciones
const
serían las funciones
abs
de
<stdlib.h>
y algunas funciones matemáticas de
<math.h>
:
sqrt
,
exp
, etc. (aunque podrían estar sujetas a modos de redondeo).
Ejemplos de funciones
pure
pero no constantes serían funciones tales como
strlen
, ya que desreferencia el puntero pasado.
Tenga en cuenta que si se pasa un puntero a una función y se examinan los contextos de ese puntero, no se puede declarar
const
, incluso si el puntero pasado y los contextos de puntero son
const
.
Esta es una limitación severa a la utilidad de
const
.
Puede devolver múltiples valores en C usando una estructura, lo que hace que sea más fácil usar
pure
.
(Es más típico usar operandos de retorno de puntero, pero esto rompe el uso de
pure
).