Primero, descubrí que no es posible definir el tipo de constante usando #define, ¿por qué?
¿Por qué es qué? No es verdad:
#define MY_INT_CONSTANT ((int) 12345)
En segundo lugar, ¿tiene alguna ventaja utilizar uno de ellos sobre el otro?
Si. #define
define una macro que se reemplaza incluso antes de que comience la compilación. const
simplemente modifica una variable para que el compilador marque un error si intenta cambiarla. Hay contextos en los que puedes usar a #define
pero no puedes usar a const
(aunque estoy luchando por encontrar uno usando el último clang). En teoría, un const
ocupa espacio en el ejecutable y requiere una referencia a la memoria, pero en la práctica esto es insignificante y puede ser optimizado por el compilador.
const
s son mucho más amigables con el compilador y el depurador que #define
s. En la mayoría de los casos, este es el punto primordial que debe considerar al tomar una decisión sobre cuál usar.
Solo piensa en un contexto en el que puedas usar #define
pero no const
. Si tiene una constante que desea usar en muchos .c
archivos, #define
simplemente péguela en un encabezado. Con a const
tienes que tener una definición en un archivo C y
const int MY_INT_CONST = 12345;
extern const int MY_INT_CONST;
en un encabezado. MY_INT_CONST
no se puede usar como el tamaño de una matriz de alcance estático o global en ningún archivo C, excepto en el que está definido.
Sin embargo, para constantes enteras, puede usar un enum
. De hecho, eso es lo que hace Apple casi invariablemente. Esto tiene todas las ventajas de #define
s y const
s, pero solo funciona para constantes enteras.
enum
{
MY_INT_CONST = 12345,
};
Finalmente, ¿de qué manera es más eficiente y / o más segura?
#define
es más eficiente en teoría aunque, como dije, los compiladores modernos probablemente aseguran que haya poca diferencia. #define
es más seguro porque siempre es un error del compilador intentar asignarle
#define FOO 5
FOO = 6;
const
Se puede engañar a s para que se asignen, aunque el compilador puede emitir advertencias:
const int FOO = 5;
(int) FOO = 6;
Dependiendo de la plataforma, la asignación aún puede fallar en tiempo de ejecución si la constante se coloca en un segmento de solo lectura y su comportamiento oficialmente indefinido de acuerdo con el estándar C.
Personalmente, para constantes enteras, siempre uso enum
s para constantes de otros tipos, uso a const
menos que tenga una muy buena razón para no hacerlo.