2010-09-28 8 views
6

J'ai la macro suivante:C préprocesseur avec instruction if

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

Le code utilisateur doit regarder ce qui suit:

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

L'accent ici sur accolades - Je veux éviter "si" de macro pour "manger" autre code:

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

Dans cet exemple IF_TRACE_ENABLED "mange" bloc autre.

Existe-t-il un moyen d'appliquer le code utilisateur non compilé sans les freins bouclés ou existe-t-il d'autres pour définir la macro pour assurer la sécurité?

+2

Je ne vois pas ce que cette macro vous donne par-dessus la simple instruction if. – JeremyP

+2

Oubliez cet exemple. Vous pourriez avoir une condition compliquée dans ce 'si 'que vous ne voulez pas répéter à chaque fois. –

+0

@JeremyP: il n'y a pas beaucoup d'utilité à avoir une macro pour cet exemple simple, mais comme Nathan indique qu'il est possible qu'il y ait plus de complexité dans la macro de débogage et/ou qu'il y ait plusieurs variantes de la Par exemple, une version de version qui évalue toujours 'false' de sorte que les chaînes de trace sont retirées de l'exécutable). –

Répondre

11

Cela ne force pas l'utilisateur de la macro à utiliser des accolades, mais il empêchera une clause else d'être sans le vouloir manger:

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

Une note de côté: accolades autour du printf() dans le second exemple de la question n'aurait pas corrigé le problème - le else associé à bla bla bla serait toujours lié à l'instruction if dans la macro.

+1

Essayer et ne pas trouver un moyen cela pourrait se retourner contre. +1 –

+0

Où est passé le contenu du bloc "si"? – dimba

+1

dans le bloc else; Bonne réponse! –

0

Cela devrait fonctionner, mais vous aurez la passer le contenu du bloc si comme argument à la macro ainsi:

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

Ceci n'est pas nécessaire printf (...). Cela pourrait être n'importe quel code qui devrait être évalué seulement quand la condition macro est vraie. – dimba

+0

Vous devez ajouter un bloc autour du contenu. –

+0

@Ronny - c'est ce que je veux forcer l'utilisateur, donc s'il oublie de le faire, la compilation va échouer – dimba

2

Vous pouvez essayer ceci:

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

I ne pense pas qu'il y ait un moyen de "forcer" une bonne syntaxe à partir de la seule ligne d'ouverture de la macro. Vous devrez utiliser deux.

EDIT

J'ai ajouté une paire supplémentaire d'accolades dans la macro pour éviter toute ambiguïté.

En réponse au commentaire, cette macro est destiné à être utilisé comme ceci:

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

Pas comme une déclaration. Pour mémoire, je pense que c'est un abus du préprocesseur et personne ne devrait le faire du tout. Quel est le problème avec juste l'écrire, entre crochets avec #ifdef DEBUG si nécessaire.

+0

La seule chose que je n'aime pas dans la solution est l'indentation du bloc entre les macros stat et stop - votre éditeur ne le mettra pas en retrait. – dimba

+1

n'est-il pas possible d'utiliser simplement les accolades, sans faire & while? –

+0

@ptmato - il y a quelque chose dans ce que dit @crypto. do/while est utilisé pour que la macro apparaisse comme une fonction normale, par cela qu'il est forcé d'utiliser ";" à la fin. Alors ";" à la fin de la macro est redondante. De toute façon nous ne ";" puisque la macro ne ressemble pas à une fonction, appelez – dimba