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. #definedefine una macro que se reemplaza incluso antes de que comience la compilación. constsimplemente modifica una variable para que el compilador marque un error si intenta cambiarla. Hay contextos en los que puedes usar a #definepero no puedes usar a const(aunque estoy luchando por encontrar uno usando el último clang). En teoría, un constocupa 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.
consts son mucho más amigables con el compilador y el depurador que #defines. 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 #definepero no const. Si tiene una constante que desea usar en muchos .carchivos, #definesimplemente péguela en un encabezado. Con a consttienes 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_CONSTno 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 #defines y consts, pero solo funciona para constantes enteras.
enum
{
MY_INT_CONST = 12345,
};
Finalmente, ¿de qué manera es más eficiente y / o más segura?
#definees más eficiente en teoría aunque, como dije, los compiladores modernos probablemente aseguran que haya poca diferencia. #definees más seguro porque siempre es un error del compilador intentar asignarle
#define FOO 5
FOO = 6;
constSe 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 enums para constantes de otros tipos, uso a constmenos que tenga una muy buena razón para no hacerlo.