2008-10-03 8 views
2

Je le divective préprocesseur suivant:#define TRACE (...) ne fonctionne pas en C++

#ifndef NDEBUG 
#define TRACE printf 
#else 
#define TRACE(...) 
#endif 

et exemple d'utilisation est:

TRACE("TRACE: some parameter = %i\n", param); 

En C tout fonctionne parfaitement bien quand je construis à la fois le débogage et publier des versions, mais dans le compilateur C++ émet les éléments suivants:

avertissement: caractère non valide dans le nom du paramètre macro

erreur: liste de paramètres mal ponctuée dans `#define '

et pointe ces avertissement et erreur vers la directive' TRACE (...) '.

Comment écrire ceci en C++ correctement?

Répondre

1

Vous pouvez faire:

inline void TRACE(...) {} 
+0

Le problème est que le compilateur doit toujours évaluer les arguments. Si elles sont chères, vous voulez les désactiver. Par conséquent, les macros de type TRACE doivent généralement évaluer le code vide en mode de libération. –

0

Quel compilateur? Pour ce que ça vaut, G ++ 4.3.1 n'a aucun problème avec ce code.

+0

Compilateur QXN Netrino QCC, version gcc_ntox86 2.95.3. Pour autant que je comprenne c'est GCC avec externsions pour la version QNX pour x86. –

3

#define TRACE false ||

Cela transforme TRACE (x, y, z) en faux || (x, y, z). Puisque x, y et z seront des expressions, (x, y, z) est évalué à z (opérateur de virgule). z doit être un type intégré (pour être légalement passé à une fonction de style printf) donc il devrait être valide sur le côté droit de ||. Il ne sera pas évalué, mais il doit être une expression légale (par exemple vous ne pouvez pas référencer les membres de classe qui existent seulement dans les builds DEBUG)

Les Vararg sont une invention C99, elles ne sont pas en C++ 98 mais pourrait très bien être en C++ 0x

[edit] - Utiliser || garantir la non-évaluation

+0

Le problème est que le compilateur doit toujours évaluer x, y et z. Si elles sont chères, vous voulez les désactiver. –