2012-06-26 12 views
15

He estado depurando un error particularmente insidioso que ahora creo que es causado por cambios inesperados que surgen de un comportamiento diferente cuando se incluyen (o no) diferentes encabezados.¿Puedo obtener el preprocesador C++ para enviar el resultado durante la compilación?

Esto no es exactamente la estructura de mi código, pero vamos a echar 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 

que busco a través de mi confirmaciones Git, y angosto hacia abajo la causa del error, compilar y ejecutar el 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 un encabezado completamente benigno y 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 accesos directos. Es solo que algunos de estos atajos, cuando no se usan con cuidado, nos muerden en el trasero bastante duro.

Así que en este punto habría ayudado si podía usar una directiva como #echo "Running old crashy code" donde voy a ser capaz de ver esto durante la compilación por lo que podría ser una propina de inmediato para empezar a investigar por qué SOME_DEFINE no se definió.

Por lo que yo sé la manera sencilla de determinar si se ha definido SOME_DEFINE es hacer algo como

#ifndef SOME_DEFINE 
    printf("SOME_DEFINE not defined!!\n"); 

Esto sin duda hacer el trabajo pero no hay una buena razón para esta tarea a llevar a cabo en tiempo de ejecución porque está completamente determinado en tiempo de compilación. Esto es simplemente algo que me gustaría ver en tiempo de compilación.

Dicho esto, en esta situación, usar la impresión (o registrar o incluso lanzar una excepción) puede ser una cosa aceptable porque no me importa realmente desacelerar o complicar el código cuestionable. Pero eso no se aplica si tengo, por ejemplo, dos rutas de código, las cuales son importantes, y solo quiero saber en tiempo de compilación cuál se está activando. Tendría que preocuparme por ejecutar el código que tiene la impresión condicionada por el preprocesador al comienzo del programa.

Esto es realmente una manera larga de hacer la pregunta, "¿Puedo hacer eco de una cadena en el resultado durante la compilación usando una directiva de preprocesador?"

+3

Usa el '#err o' directiva? O '# warning', si el preprocesador lo admite. –

+0

'# warning' es más parecido, ya que no detendrá el procesamiento. Pero sí, eso es más o menos. Por favor, haz una respuesta! –

+0

Creo que también hay '# warn' \' # warning' en algunos compiladores, pero creo que no es estándar y es menos universal. También he visto '#pragma message (" WARN ")' y '# print' disponible en algunos. – jedwards

Respuesta

18

Si utiliza la directiva #error, la salida se imprime 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 
$ 

Esto podría no ser exactamente lo que quería, pero hace el trabajo rápidamente.

$ cat days_in_month.c 
#include <stdio.h> 
#error "ugly!" 
... 

Si desea procesamiento de continuar, puede utilizar #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!" 
+0

Esto producirá una salida que es fácil de ver. Realmente estaba esperando una opción donde pueda definir la cadena exacta que escupe (para que pueda ser tan visible como yo quiera) pero esto hará el trabajo. –

+0

Tenga en cuenta que puede colocar lo que desee en la cadena; Si querías una pantalla completa de bloques de "XXX ADVERTENCIA XXX", no te gusta. :) (¿Me pregunto si los escapes de color de la terminal también se transmiten?) – sarnold

+0

@Linuxios: ese fue mi primer intento ... :) Mi primera versión de esta respuesta fue simplemente '# error', hasta que pensé en probar algo más detallado - - Estaba seguro de haber visto una forma de introducir solo una advertencia. – sarnold

Cuestiones relacionadas