ProgramaciónDesarrollador C

Hable sobre las diferencias clave entre const y #define para definir constantes en el lenguaje C. Cuándo y por qué usar cada enfoque, con ejemplos de errores comunes.

Supere entrevistas con el asistente de IA Hintsage

Respuesta.

#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.

Cuándo y por qué usar:

  • #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).
  • Para punteros a cadenas y matrices, es preferible usar 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 capciosa.

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 int para 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.