2010-09-28 42 views
6

tengo la siguiente macro:C preprocesador con la sentencia if

#define IF_TRACE_ENABLED(level) if (IsTraceEnabled(level)) 

El código de usuario debe buscar siguiente:

IF_TRACE_ENABLED(LEVEL1) 
{ 
    ... some very smart code 
} 

El énfasis aquí en corchetes - Quiero evitar el "si" de macro "comer" otro código:

if (...) 
    IF_TRACE_ENABLED(LEVEL1) 
     printf(....); 
else 
    bla bla bla 

En este ejemplo IF_TRACE_ENABLED "come" bloque else.

¿Hay forma de hacer cumplir el código de usuario no compilar sin los frenos o hay otros para definir la macro para lograr la seguridad?

+2

No veo lo que esa macro le da sobre la declaración desnuda si. – JeremyP

+2

Olvídate de este ejemplo. Podría tener una condición complicada en ese 'si' que no desea repetir cada vez. –

+0

@JeremyP: no hay mucha utilidad en tener una macro para este ejemplo simple, pero como Nathan indica que es posible que haya más complejidad en la macro de depuración y/o que haya varias variaciones de la macro en función de la configuración de compilación (para ejemplo, una versión de lanzamiento que siempre se evalúa como 'false' para que las cadenas de rastreo se eliminen del ejecutable). –

Respuesta

11

Esto no fuerza al usuario de la macro de utilizar los frenos, pero evitará una else cláusula de ser comido involuntariamente:

#define IF_TRACE_ENABLED(level) if (!IsTraceEnabled(level)) {} else 

una nota: los frenos de todo el printf() en el segundo ejemplo de la pregunta no habría solucionado el problema: el else asociado con bla bla bla seguiría vinculado a la declaración if en la macro.

+1

Probar y no encontrar una forma de que esto pueda ser contraproducente. +1 –

+0

¿Dónde se pasa el contenido del bloque "if"? – dimba

+1

en el bloque else; ¡buena respuesta! –

0

Esto debería funcionar, pero tendrá el Paso de los contenidos del bloque if como un argumento a la macro, así:

#define IF_TRACE_ENABLED(level,content) { if (IsTraceEnabled(level)) {content} } 
+0

Esto no es necesario printf (...). Este podría ser cualquier código que debería evaluarse solo cuando la condición macro es verdadera. – dimba

+0

Debe agregar un bloque alrededor del contenido. –

+0

@Ronny: esto es lo que quiero aplicar al usuario, por lo que si olvida hacerlo, la compilación fallará – dimba

2

Usted podría intentar esto:

#define IF_TRACE_ENABLED(level) do { if(IsTraceEnabled(level)) { 
#define END_TRACE_ENABLED } } while(0); 

I no creo que haya ninguna forma de "aplicar" una buena sintaxis solo desde la línea de apertura de la macro. Necesitarás usar dos.

EDITAR

He añadido un par extra de llaves dentro de la macro para evitar toda ambigüedad.

En respuesta al comentario, esta macro está destinado a ser utilizado como esto:

IF_TRACE_ENABLED(LEVEL1) 
    printf("Trace\n"); 
END_TRACE_ENABLED 

No como un comunicado. Para el registro, creo que esto es un abuso del preprocesador y nadie debería hacer esto en absoluto. ¿Qué pasa con solo escribirlo, entre corchetes con #ifdef DEBUG si es necesario?

+0

Lo único que no me gusta de la solución es la sangría del bloque entre las macros stat y stop - su editor no lo sangrará. – dimba

+1

¿No es posible simplemente usar los refuerzos, sin hacer y mientras? –

+0

@ptmato - hay algo en lo que dice @crypto. do/while se usa para que macro se vea como una función normal, por lo que se le obliga a usar ";" en el final. Asi que ";" al final de la macro es redundante. Cualquier forma en que no lo hagamos ";" dado que la macro no se parece a una función, llame al – dimba

Cuestiones relacionadas