“const estática” frente a “#define” frente a “enumeración”

5 minutos de lectura

avatar de usuario
Vijay

¿Cuál es mejor usar entre las siguientes declaraciones en C?

static const int var = 5;

o

#define var 5

o

enum { var = 5 };

  • Curiosamente, esto es casi exactamente la misma pregunta que stackoverflow.com/questions/1637332/static-const-vs-define. La única diferencia es que esa pregunta es sobre C++, y esta es sobre C. Dado que mi respuesta fue específica de C++, digo que eso los hace no idénticos, pero otros pueden no estar de acuerdo.

    – TED

    4 de noviembre de 2009 a las 15:09

  • No idénticos, definitivamente. Hay muchas áreas en las que C++ permite la sintaxis de C por motivos de compatibilidad. En esos casos, preguntas como “¿cuál es la mejor forma de hacer X?” tendrán respuestas diferentes en C++. Por ejemplo, inicialización de objetos.

    – MSalters

    4 de noviembre de 2009 a las 15:33

  • También: stackoverflow.com/questions/1944041/…

    – jamesdlin

    10 de agosto de 2017 a las 2:07

  • ¿Cómo es que esto no está basado en opiniones? Cada uno tiene un propósito diferente

    – Sam Hammamy

    28 de diciembre de 2017 a las 13:28


  • wiki.sei.cmu.edu/confluence/display/c/…

    – chispeante

    22 de junio de 2019 a las 23:15

avatar de usuario
envoltorio

La diferencia entre static const y #define es que el primero usa la memoria y el segundo no usa la memoria para el almacenamiento. En segundo lugar, no puede pasar la dirección de un #define mientras que puede pasar la dirección de un static const. En realidad, depende de la circunstancia en la que nos encontremos, debemos seleccionar uno entre estos dos. Ambos están en su mejor momento bajo diferentes circunstancias. Por favor, no asuma que uno es mejor que el otro… 🙂

Si ese hubiera sido el caso, dennis ritchie me hubiera quedado solo con el mejor… jajaja… 🙂

  • +1 por mencionar la memoria, algunos sistemas integrados aún no tienen tanto, aunque probablemente comenzaría usando constantes estáticas y solo cambiaría a #defines si fuera necesario.

    – fluffyben

    7 de marzo de 2012 a las 11:36

  • Acabo de probarlo. De hecho, const int usa memoria adicional en comparación con #define o enum. Dado que programamos sistemas integrados, no podemos permitirnos el uso de memoria adicional. Entonces, volveremos a usar #define o enum.

    – Davide Andrea

    2 de marzo de 2015 a las 17:51

  • Prácticamente hablando, no es cierto (ya) que un const usa memoria. GCC (probado con 4.5.3 y algunas versiones más nuevas) optimiza fácilmente el const int en un literal directo en su código cuando usa -O3. Entonces, si realiza un desarrollo integrado con poca RAM (por ejemplo, AVR), puede usar con seguridad C consts si usa GCC u otro compilador compatible. No lo he probado, pero espero que Clang haga lo mismo por cierto.

    – Rafael

    10 dic 2015 a las 18:43

avatar de usuario
Interrupción no enmascarable

#define var 5 te causará problemas si tienes cosas como mystruct.var.

Por ejemplo,

struct mystruct {
    int var;
};

#define var 5

int main() {
    struct mystruct foo;
    foo.var = 1;
    return 0;
}

El preprocesador lo reemplazará y el código no se compilará. Por esta razón, el estilo de codificación tradicional sugiere todas las constantes #defines utiliza letras mayúsculas para evitar conflictos.

avatar de usuario
Pedro Mortensen

En C, específicamente? En C la respuesta correcta es: use #define (o, en su caso, enum)

Si bien es beneficioso tener las propiedades de alcance y tipificación de un const objeto, en realidad const los objetos en C (a diferencia de C++) no son verdaderas constantes y, por lo tanto, suelen ser inútiles en la mayoría de los casos prácticos.

Entonces, en C, la elección debe estar determinada por cómo planea usar su constante. Por ejemplo, no puede utilizar un const int objeto como un case etiqueta (mientras que una macro funcionará). no puedes usar un const int objeto como un ancho de campo de bits (mientras que una macro funcionará). En C89/90 no puedes usar un const objeto para especificar un tamaño de matriz (mientras que una macro funcionará). Incluso en C99 no puedes usar un const objeto para especificar un tamaño de matriz cuando necesita un objeto que no seaVLA formación.

Si esto es importante para usted, determinará su elección. La mayoría de las veces, no tendrá más remedio que usar #define en C. Y no olvide otra alternativa, que produce verdaderas constantes en C – enum.

En C++ const los objetos son verdaderas constantes, por lo que en C++ casi siempre es mejor preferir el const variante (sin necesidad de explícita static aunque en C++).

avatar de usuario
Pedro Mortensen

La definición

const int const_value = 5;

no siempre define un valor constante. Algunos compiladores (por ejemplo tcc 0.9.26) simplemente asigne memoria identificada con el nombre “const_value”. Usando el identificador “const_value” no puedes modificar esta memoria. Pero aún podría modificar la memoria usando otro identificador:

const int const_value = 5;
int *mutable_value = (int*) &const_value;
*mutable_value = 3;
printf("%i", const_value); // The output may be 5 or 3, depending on the compiler.

Esto significa que la definición

#define CONST_VALUE 5

es la única manera de definir un valor constante que no puede ser modificado por ningún medio.

  • Modificar un valor constante usando un puntero es un comportamiento indefinido. Si estás dispuesto a ir allí, #define también se puede modificar, editando el código máquina.

    – ugoren

    12 de junio de 2013 a las 13:57

  • Tienes razón en parte. Probé el código con Visual Studio 2012 y se imprime 5. Pero uno no puede modificar #define porque es una macro de preprocesador. No existe en el programa binario. Si uno quisiera modificar todos los lugares donde CONST_VALUE fue usado, había que hacerlo uno por uno.

    – usuario2229691

    19 de octubre de 2013 a las 7:28


  • @ugoren: Supongamos que escribes #define CONST 5entonces if (CONST == 5) { do_this(); } else { do_that(); }y el compilador elimina el else sucursal. ¿Cómo propone editar el código de máquina para cambiar CONST a las 6?

    –Keith Thompson

    26 de febrero de 2014 a las 16:47

  • @KeithThompson, nunca dije que se pueda hacer de manera fácil y confiable. Solo eso #define no es a prueba de balas.

    – ugoren

    26 de febrero de 2014 a las 18:12


  • @ugoren: Mi punto es que “editar el código de la máquina” no es una forma sensata de duplicar el efecto de cambiar el valor de un #define. La única forma real de hacerlo es editar el código fuente y volver a compilar.

    –Keith Thompson

    26 de febrero de 2014 a las 19:04

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad