2010-11-04 12 views
18

Tengo un conjunto de macros de depuración en tracing.hh. Tanto si se genera el código y la salida es controlada por una bandera macro en el código fuente real:Prueba de definición de macro vacía

// File: foo.cc 
#define TRACING 0 
#include "tracing.hh" 
// Away we go . . . 
TRACEF("debug message"); 

El trazado bandera debe tener un valor; Por lo general alternar entre 0 y 1.

Dentro tracing.h,

  • #ifdef TRACING me dirá que el seguimiento se definió.
  • #if TRACING controla la definición de macros funcionales como TRACEF()

pero lo que si RASTREO no tiene valor? Entonces #if TRACING produce un error:

In file included from foo.c:3: 
tracing.hh:73:12: error: #if with no expression 

¿Cómo se puede probar que si se define RASTREO pero no tiene valor?

Respuesta

0

¿Sería

#if defined(TRACING) && !TRACING 

hacer el truco?

+0

Casi, creo. Ver la respuesta siguiente: – pdbj

+4

Desafortunadamente, esto no funcionará. Encontrará el mismo problema, donde se eliminará el RASTREO. Usted terminará con algo como: "# si está definido (RASTREO) &&!". Por lo tanto, "error: operator '!' no tiene un operando correcto "aumentará en tiempo de compilación. – ForceMagic

22

Con la sugerencia de Matti y algo más, creo que el problema es este: si TRACING no tiene ningún valor, necesitamos una expresión de preprocesador válida en la prueba #if .... El Gnu cpp manual dice que tiene que evaluar en una expresión entera, por lo que necesitamos una expresión que sea válida incluso si uno de los argumentos falta. Lo que finalmente me ocurrió es:

#if (TRACING + 0) 
# . . . 
  • Si TRACING tiene un valor numérico (como en #define TRACING 2 \n), CPP tiene una expresión válida, y no hemos cambiado el valor
  • Si TRACING no tiene ningún valor. (como en #define TRACING \n), el preprocesador evalúa #if (+0) a false

el único caso esto no es manejar

  • Si TRACING tiene un valor de contador (es decir, ON). El manual de cpp dice "Identificadores que no son macros ... todos son considerados como el número cero," que evalúa a false. En este caso, sin embargo, tendría más sentido considerar esto como un valor de true. Los únicos tokens que hacen lo correcto son los literales booleanos true y false.
+0

Aún puede hacer una prueba en tiempo de ejecución haciendo que la macro sea una cadena utilizando el operador '#'. C++ 11 puede convertirlo en una prueba en tiempo de compilación (supongo que usar 'constexpr' podría ser una forma) pero no un preprocesador. –

+0

tampoco tiene medios para distinguir entre vacío y 'TRACING 'es igual a 0 –

+0

' # if' define a 0 si no se encuentra. eso no funciona –

1

tarde a la fiesta, pero me encontré con un buen truco para distinguir -DTRACING=0 de -DTRACING:

#if (0-TRACING-1)==1 && (TRACING+0)!=-2 
#error "tracing empty" 
#endif 

Si TRACING está vacía, la expresión se evalúa 0--1 =>1.

Si TRACING es 0, la expresión se evalúa 0-0-1 =>-1

he añadido una comprobación adicional en caso de TRACING==-2 que haría que la primera serie de pruebas.

Esto no funciona para literales de cadena, por supuesto.

Cuestiones relacionadas