Como se ha discutido en varias preguntas recientes, declarar const
-variables calificadas en C (en oposición a const
variables en C++, o punteros a const
en C) generalmente sirve para muy poco propósito. Lo más importante es que no se pueden usar en las expresiones constantes .¿Cuáles son algunos usos prácticos para las variables const const en C?
Dicho esto, ¿cuáles son algunos usos legítimos de const
variables calificadas en C? Puedo pensar en algunos que han aparecido recientemente en el código con el que he trabajado, pero seguramente debe haber otros. Aquí está mi lista:
usando sus direcciones como valores especiales centinela para un puntero, así como nunca comparar igual a cualquier otro puntero. Por ejemplo:
char *sentinel(void) { static const char s; return &s; }
o simplementeconst char sentinel[1];
Dado que solo nos importa la dirección y en realidad no importaría si el objeto se escribió, el único beneficio deconst
es que los compiladores generalmente lo almacenan en la memoria de solo lectura respaldada pormmap
de el archivo ejecutable o una copia de la página cero.Utilizando
const
variables calificadas para exportar valores de una biblioteca (especialmente bibliotecas compartidas), cuando los valores podrían cambiar con las nuevas versiones de la biblioteca. En tales casos, simplemente usar#define
en el encabezado de la interfaz de la biblioteca no sería un buen enfoque porque haría que la aplicación dependa de los valores de las constantes en la versión particular de la biblioteca con la que se creó.estrechamente relacionado con el uso previo, a veces desea exponer objetos predefinidos de una biblioteca para la aplicación (los ejemplos por excelencia siendo
stdin
,stdout
ystderr
de la librería estándar). Con ese ejemplo,extern FILE __stdin; #define stdin (&__stdin)
sería una implementación muy mala debido a la forma en que la mayoría de los sistemas implementan bibliotecas compartidas; generalmente requieren que se copie el objeto completo (aquí,FILE
) a una dirección determinada cuando la aplicación está vinculada e introducen una dependencia en el tamaño del objeto (el programa se romperá si la biblioteca se reconstruye y el tamaño del objeto cambia). El uso de un punteroconst
(no puntero aconst
) aquí corrige todos los problemas:extern FILE *const stdin;
, donde el punteroconst
se inicializa para apuntar al objeto predefinido (que probablemente se declarestatic
) en algún lugar interno de la biblioteca.Tablas de búsqueda para funciones matemáticas, propiedades de caracteres, etc. Este es el obvio que olvidé incluir originalmente, probablemente porque estaba pensando en variables individuales de tipo aritmético/puntero, ya que ahí fue donde surgió el tema de pregunta arriba. Gracias a Aidan por haberme hecho recordar.
Como una variante en tablas de búsqueda, implementación de máquinas de estados. Aidan proporcionó un ejemplo detallado como respuesta. He encontrado que el mismo concepto también suele ser muy útil sin ningún puntero a la función, si puede codificar el comportamiento/las transiciones de cada estado en términos de unos pocos parámetros numéricos.
Alguien más tiene algunos usos inteligentes y prácticas para las variables const
Calificado en C?
Mientras esto funciona, no veo la ventaja sobre '#define my_inport (* (unsigned char const volátil *) 0x00FA)' y luego solo puedo hacer 'c = my_inport;' Mi versión probablemente se compilaría para código más pequeño/más eficiente porque es una expresión constante, mientras que la versión con las variables 'const' en realidad podría cargar la dirección indirectamente cada vez que se usa. –
Este es básicamente el argumento antiguo de las constantes '# define' contra las constantes' const'. En general, ninguno es mejor o peor que el otro. Es solo que uno es un constructo de lenguaje y uno es un comando de preprocesador. A menudo se pasa por alto que un lenguaje de programación no es más que un conjunto de instrucciones para que un programa interprete. En el caso de C, el programa es un compilador cuyo trabajo es producir un código de ensamblaje optimizado. Entonces, usar construcciones de lenguaje debería proporcionarle más información y permitirle producir un resultado más relevante. Sin embargo, esto se pierde con '# define's. – DuFace