¿Cuándo y con qué fines debería usarse la palabra clave const en C para las variables?

48

Al obtener mi código revisado aquí el problema de usar const palabra clave surgió. Entiendo que se usa para implementar el comportamiento de solo lectura en las variables.

Estoy confundido acerca de cuáles son las diversas situaciones en las que puede ser útil.

  • ¿Debería usarse en aras de la claridad en los prototipos de funciones?
  • ¿Debería usarse como medida de seguridad durante el desarrollo del código?
  • ¿Debería usarse en el alcance de varias funciones para declarar constantes de tiempo de ejecución?
  • ¿Debería usarse en absoluto?

Estas preguntas son solo ejemplos de la confusión que estoy enfrentando. La confusión general es

  • ¿Cuándo debería ser la palabra clave const utilizada en la programación en C?
  • ¿Cuáles son los diversos tipos de beneficios que se pueden obtener al usar esta palabra clave en C?
  • ¿Hay algún inconveniente al utilizar la palabra clave const ?

Se ha señalado que esta pregunta puede ser demasiado amplia debido a todas estas preguntas en el detalle de mi pregunta. Solo quería aclarar que estas preguntas son solo para aclarar la confusión con respecto a la pregunta principal.
  

¿Cuándo y para qué se debe usar la palabra clave const en C para variables?

También se puede reformular como

  

El uso correcto de la palabra clave const en C 'con las ventajas y desventajas de la misma.

    
pregunta Aseem Bansal 11.07.2013 - 16:04

4 respuestas

55

Al revisar el código, aplico las siguientes reglas:

  • Siempre use const para los parámetros de función pasados por referencia donde La función no modifica (ni libera) los datos a los que apunta.

    int find(const int *data, size_t size, int value);
    
  • Siempre use const para las constantes que de otra manera podrían definirse usando #define o enum. El compilador puede ubicar los datos en la memoria de solo lectura (ROM) como resultado (aunque el vinculador es a menudo una mejor herramienta para este propósito en sistemas integrados).

    const double PI = 3.14;
    
  • Nunca use const en una función prototipo para un parámetro pasado valor . No tiene significado y por lo tanto es solo 'ruido'.

    // don't add const to 'value' or 'size'
    int find(const int *data, size_t size, const int value); 
    
  • Cuando sea apropiado, use const volatile en ubicaciones que el programa no puede cambiar pero que aún pueden cambiar. Los registros de hardware son el caso de uso típico aquí, por ejemplo, un registro de estado que refleja el estado de un dispositivo:

    const volatile int32_t *DEVICE_STATUS =  (int32_t*) 0x100;
    

Otros usos son opcionales. Por ejemplo, los parámetros de una función dentro de la función implementación se pueden marcar como const.

// 'value' and 'size can be marked as const here
int find(const int *data, const size_t size, const int value)  
{
     ... etc

o función devuelve valores o cálculos que se obtienen y luego nunca cambian:

char *repeat_str(const char *str, size_t n) 
{
    const size_t len = strlen(str);
    const size_t buf_size = 1 + (len * n);
    char *buf = malloc(buf_size);
    ...

Estos usos de const solo indican que no cambiará la variable; no cambian cómo o dónde se almacena la variable. Por supuesto, el compilador puede determinar que una variable no se modifica, pero al agregar const , se permite que se cumpla. Esto puede ayudar al lector y agregar algo de seguridad (aunque si sus funciones son grandes o Lo suficientemente complicado como para que esto haga una gran diferencia, posiblemente tenga otros problemas). Editar - por ejemplo. Una función codificada densamente de 200 líneas con bucles anidados y muchos largos o nombres de variables similares, sabiendo que ciertas variables nunca cambian podrían Facilidad de entender significativamente. Tales funciones han sido mal diseñadas o Mantenido.

Problemas con const . Probablemente escuchará el término "envenenamiento constante". Esto ocurre cuando la adición de const a un parámetro de función hace que 'constness' propagar.

Editar - envenenamiento por const: por ejemplo en la función:

int function_a(char * str, int n)
{
    ...
    function_b(str);
    ...
}

si cambiamos str a const , entonces debemos asegurarnos de que fuction_b también tome un codigo%. Y así sucesivamente si const pasa el function_b a str , Como puede imaginar, esto podría ser doloroso si se propaga en muchos archivos / módulos separados. Si se propaga en una función que no puede ser cambiado (por ejemplo, una biblioteca del sistema), entonces se hace necesario un lanzamiento. Así que espolvorear Tal vez el function_c en el código existente está pidiendo problemas. En código nuevo sin embargo, es mejor que const califique consistentemente cuando sea apropiado.

El problema más insidioso de const es que no estaba en el original idioma. Como complemento no encaja del todo. Para empezar tiene dos significados. (como en las reglas anteriores, que significa "no voy a cambiar esto" y "esto no se puede modificar"). Pero más que eso, puede ser peligroso. Por ejemplo, compilar y ejecute este código y (dependiendo del compilador / opciones) puede bloquearse cuando ejecutar:

const char str[] = "hello world\n";
char *s = strchr(str, '\n');
*s = '
int find(const int *data, size_t size, int value);
';

const devuelve un strchr no un char* . Como su parámetro de llamada es const char* debe convertir el parámetro de llamada a const . Y en este caso que desecha la propiedad de almacenamiento de sólo lectura real. Editar: - esto se aplica generalmente a las variables en la memoria de solo lectura. Por "ROM", me refiero no solo a la ROM física, sino a cualquier memoria que esté protegida contra escritura, como sucede en la sección de código de los programas que se ejecutan en un sistema operativo típico.

Muchas funciones de biblioteca estándar se comportan de la misma manera, así que ten cuidado: cuando tiene constantes de real (es decir, almacenadas en la ROM), debe tener mucho cuidado de no perder su constness.

    
respondido por el William Morris 13.07.2013 - 16:05
7

Generalmente, en cualquier lenguaje de programación se recomienda usar const o el modificador equivalente desde

  • Puede aclarar a la persona que llama que lo que pasaron no va a cambiar
  • Mejoras potenciales de velocidad ya que el compilador sabe con certeza que puede omitir ciertas cosas que solo son relevantes si el parámetro puede cambiar
  • Protección de ti mismo cambiando accidentalmente el valor
respondido por el TheLQ 11.07.2013 - 17:05
1

Sí, es básicamente la respuesta de TheLQ.

Es una medida de seguridad para el programador, por lo que no modifica una variable y no llama a funciones que pueden modificarla. En una matriz o estructura, el especificador const indica que los valores de su contenido no se modificarán, e incluso el compilador no le permitirá hacerlo. Sin embargo, aún puede cambiar fácilmente el valor de la variable con solo una conversión.

En lo que generalmente veo, se usa principalmente para agregar valores constantes en el código y para indicar que la matriz o estructura no se modificará si llama a una función en particular. Esta última parte es importante, porque cuando llama a una función que MODIFICARÁ su matriz o estructura, es posible que desee conservar la versión original, de modo que cree una copia de la variable y luego la pase a la función. Si ese no es el caso, no necesita la copia, obviamente, así que, por ejemplo, puede cambiar,

int foo(Structure s);

a

int foo(const Structure * s);

y no obteniendo la sobrecarga de copia.

Solo para agregar, tenga en cuenta que C tiene reglas particulares con el especificador const. Por ejemplo,

int b = 1;
const int * a = &b;

no es lo mismo que

int b = 1;
int * const a = &b;

El primer código no le permitirá modificar a. En el segundo caso, el puntero es constante pero su contenido no lo es, por lo que el compilador le permitirá decir * a = 3; sin un error de compilación, pero no puede hacer que a sea una referencia a otra cosa.

    
respondido por el lgarcia 13.07.2013 - 15:09
0

De acuerdo con las declaraciones de TheLQ:

Cuando trabajar con un equipo de programadores que declaran const es una buena manera de indicar que dicha variable no debe modificarse, o simplemente para recordarse en grandes proyectos. Es útil en ese sentido y puede ahorrar muchos dolores de cabeza.

    
respondido por el David Otano 13.07.2013 - 14:19

Lea otras preguntas en las etiquetas