Macro de débogage du préprocesseur pour la journalisation facultative
-
05-07-2019 - |
Question
J'aimerais coder dans certaines macros de pré-processeur pour éventuellement enregistrer certaines informations. Par exemple dans le .h
//#define ML_DEBUG(x) (x) // flip this bit to do the error logging
#define ML_DEBUG(x) (1==1) // flip this bit to silence
dans le fichier .m je m’implémente comme:
ML_DEBUG(NSLog(@"Class dealloc: %@", [NSString stringWithCString:object_getClassName(self)]));
Le code fonctionne bien tel que je l’ai présenté. Cependant, je ne pense pas que mon " ne fais rien " le boîtier est aussi léger qu'il pourrait l'être. Je m'attendais à écrire:
//#define ML_DEBUG(x) (x) // flip this bit to do the error logging
#define ML_DEBUG(x) (;) // flip this bit to silence
Etant donné qu'un seul point-virgule est une instruction objective-c valide, je m'attendais à ce que cela fonctionne, mais le compilateur me dit:
expected expression before ';' token
Ma question est la suivante: ai-je choisi le plus léger "ne rien faire"? instruction en utilisant 1 == 1
ou existe-t-il un moyen moins intensif de le faire. Ou peut-être que toute mon approche de la journalisation de débogage temporaire est erronée?
La solution
La chose la plus simple est une définition vide:
#define ML_DEBUG(x)
Cela fonctionne dans la plupart des cas, mais pas avec l'opérateur ternaire, par exemple:
.something ? ML_DEBUG(x) : ML_DEBUG(y);
Afin de travailler pour cet exemple (certes artificiel), vous pouvez le faire:
#define ML_DEBUG(x) ((void)0)
Il est tout à fait correct de convertir des éléments en un élément vide - cela indique au compilateur que vous ignorez explicitement le résultat de l'expression.
C’est pour cette raison que la macro ANSI C standard assert ()
est transformée en ((void) 0)
lorsque NDEBUG
est défini au lieu de l'instruction vide.