preprocesador - los tres tipos de datos básicos en lenguaje c++ son
¿Puedo obtener el preprocesador de C++ para enviar resultados durante la compilación? (2)
La respuesta más acorde con lo que estaba buscando está aquí: https://stackoverflow.com/a/3826876/340947
Lo siento @sarnold
He estado depurando un error particularmente insidioso que ahora creo que se debe a cambios inesperados que se derivan de diferentes comportamientos cuando se incluyen (o no) diferentes encabezados.
Esta no es exactamente la estructura de mi código, pero echemos un vistazo a este escenario:
#include "Newly_created_header_which_accidentally_undefines_SOME_DEFINE.h"
// ...
#ifdef SOME_DEFINE
code_which_i_believe_i_am_always_running();
#else
code_which_fails_which_i_have_forgotten_about(); // runtime error stack traces back here, but I don''t know this... or maybe it''s some strange linker error
#endif
Busco a través de mis confirmaciones de git y reduzco la causa del error, compilando y ejecutando mi código innumerables veces, solo para descubrir después de varias horas que la única diferencia requerida para causar el error es la inclusión de lo que parece ser completamente benigno. encabezado no relacionado.
Quizás este es un gran argumento para explicar por qué el preprocesador simplemente apesta.
Pero me gusta. El preprocesador es genial porque nos permite hacer atajos. Es solo que algunos de estos atajos, cuando no se usan con cuidado, nos pican en el trasero bastante fuerte.
Entonces, en esta coyuntura, me habría ayudado si pudiera usar una directiva como #echo "Running old crashy code"
donde podré ver esto durante la compilación, así podría recibir información inmediata para comenzar a investigar por qué no se definió SOME_DEFINE.
Por lo que sé, la forma sencilla de determinar si SOME_DEFINE está definido es hacer algo como
#ifndef SOME_DEFINE
printf("SOME_DEFINE not defined!!/n");
Esto seguramente hará el trabajo, pero no hay una buena razón para que esta tarea se realice en tiempo de ejecución porque está completamente determinada en el momento de la compilación. Esto es simplemente algo que me gustaría ver en tiempo de compilación.
Dicho esto, en esta situación, el uso de la impresión (o el registro o incluso el lanzamiento de una excepción) puede ser una cosa aceptable, ya que no me importará realmente frenar o saturar el código cuestionable. Pero eso no se aplica si, por ejemplo, tengo dos rutas de código que son importantes, y solo quiero saber en el momento de la compilación cuál se está activando. Tendría que preocuparme por ejecutar el código que hace la impresión condicionada por el preprocesador al comienzo del programa.
Esta es realmente una manera larga de formular la pregunta: "¿Puedo hacer una cadena de eco en la salida durante la compilación utilizando una directiva de preprocesador?"
Si utiliza la directiva #error
, la salida se imprimirá directamente y la compilación se detendrá:
$ make days_in_month
cc days_in_month.c -o days_in_month
days_in_month.c:2:2: error: #error "ugly!"
make: *** [days_in_month] Error 1
$
Puede que esto no sea exactamente lo que quería, pero hace el trabajo rápidamente.
$ cat days_in_month.c
#include <stdio.h>
#error "ugly!"
...
Si desea que el procesamiento continúe, puede usar #warning
:
$ make days_in_month
cc days_in_month.c -o days_in_month
days_in_month.c:2:2: warning: #warning "ugly!" [-Wcpp]
$ head days_in_month.c
#include <stdio.h>
#warning "ugly!"