¿Cuál es mejor usar entre las siguientes declaraciones en C?
static const int var = 5;
o
#define var 5
o
enum { var = 5 };
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 };
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
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 #define
s utiliza letras mayúsculas para evitar conflictos.
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++).
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 5
entonces 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
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