#define es una directiva del preprocesador que simplemente reemplaza todas las ocurrencias del identificador por el valor antes de la compilación. No crea variables, no conoce tipos, no verifica límites y no respeta el alcance.
const es un calificador que crea una verdadera variable, pero bloqueada para escritura después de la inicialización. Una variable const tiene tipo, alcance, participa en la depuración y puede ser más segura. Dichas variables se colocan en la sección .rodata o en la pila/en memoria.
#define — para valores escalares simples que son necesarios en el momento de la compilación, especialmente si se utilizan en condiciones del preprocesador o tamaños de matriz (#define SIZE 16).const — para valores que se deben pasar de manera segura por tipo, depurar y exportar de forma segura (en archivos de encabezado, entre módulos).const.Ejemplo:
#define PI 3.14159 const double G = 9.81; int arr[PI]; // ¡ERROR! PI no es un entero int arr2[G]; // ¡ERROR! G no es un valor conocido en tiempo de compilación
Pregunta: ¿Funciona const int a = 10; como una constante de tiempo de compilación para crear un arreglo: int arr[a];?
Respuesta: No. En el lenguaje C, const es un calificador, pero la variable se crea e inicializa en tiempo de ejecución, no en tiempo de compilación, por lo que el tamaño del arreglo debe ser un literal o una expresión conocida por el compilador. Use #define, o enum { SIZE = 10 };.
Ejemplo de error:
const int a = 5; int arr[a]; // En C89/90 no funcionará (VLAs aparecieron en C99, pero no en todas partes)
Historia
En un servidor multimedia intentaron usar
const intpara definir el tamaño del búfer, pensando que era una "constante de tiempo de compilación". En un compilador (GCC, C99) todo funcionó, pero en la mayoría hubo un error de compilación (VLA no es soportado), se reescribió urgentemente a #define.
Historia
En código dependiente de la plataforma, definieron una cadena a través de
#define NAME "MyApp", la usaron en varios lugares y olvidaron encerrarla entre paréntesis. Después de agregar caracteres a la cadena sin paréntesis explícitos, obtuvieron resultados incorrectos que llevaron a errores extraños en los registros.
Historia
En un proyecto con varios módulos definieron una constante a través de #define en dos lugares con valores diferentes (copia y pega). El resultado — los módulos trabajaron con diferentes constantes, dañando la unificación de datos, que solo se corrigió con una depuración meticulosa.