preprocessor c-preprocessor

preprocessor - Prueba de definición de macro vacía



c-preprocessor (3)

Tengo un conjunto de macros de depuración en tracing.hh. Si genera código y la salida se controla mediante un indicador de macro en el código fuente real:

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

La marca TRACING debe tener un valor; Normalmente alterno entre 0 y 1.

Dentro del rastreo.h,

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

Pero ¿y si TRACING 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 puedo probar si TRACING está definido pero no tiene valor?


Con la sugerencia de Matti y algo más de curiosidad, creo que el problema es el siguiente: si TRACING no tiene ningún valor, necesitamos una expresión de preprocesador válida en la prueba #if ... El manual de Gnu cpp dice que tiene que evaluar una expresión entera, por lo que necesitamos una expresión que sea válida incluso si falta uno de los argumentos. Lo que finalmente encontré 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) como false

El único caso que este no maneja es

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

Tarde a la fiesta, pero encontré 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ío, la expresión se evalúa como 0--1 => 1 .

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

Agregué un cheque adicional en el caso de TRACING==-2 que haría que la primera prueba pasara.

Esto no funciona para los literales de cuerdas, por supuesto.


haría

#if defined(TRACING) && !TRACING

¿Haz el truco?