2009-08-20 4 views
4

Dites que j'ai une fonction C++ debugPrint (int foo). Comment est-ce que je peux le plus commodément dépouiller cela des versions de libération? Je ne veux pas entourer chaque appel à debugPrint aveC#ifdefs car cela prendrait beaucoup de temps. D'un autre côté, je veux être sûr à 100% que le compilateur supprime tous les appels à cette fonction, et la fonction elle-même à partir des versions libérées. L'effacement devrait également avoir lieu, s'il est appelé avec un paramètre résultant d'un appel de fonction. Par exemple, debugPrint (getFoo()) ;. Dans ce cas, je veux également que l'appel getFoo() soit supprimé. Je comprends que la fonction inline peut être une option, mais inline n'est pas garanti pour être pris en charge.Comment faire pour supprimer le code de débogage lors de la compilation en C++?

+1

La seule façon d'éliminer 'getFoo()' 'dans debugPrint (getFoo())' est d'utiliser macro. Mais cela conduira à ce que votre programme se comportera différemment dans les configurations de débogage et de libération. C'est vraiment dangereux. –

+1

Il est dangereux si getFoo() a une logique cachée autre que l'obtention d'une valeur de foo variable. Mais c'est un mauvais code. – juvenis

Répondre

13

Utiliser la compilation conditinal et une macro:

#ifdef _DEBUG 
    #define LOG(x) debugPrint(x) 
#else 
    #define LOG(x) 
#endif 

Define _DEBUG pour la version de débogage et définit pas pour la version release. Maintenant, dans la version construire chaque

LOG(blahbhahblah); 

sera étendu dans une chaîne vide - même les paramètres ne seront pas évaluées et ne seront pas inclus dans le code émis.

Vous pouvez utiliser n'importe quel symbole de préprocesseur existant défini dans la version de débogage et non défini dans la version au lieu de _DEBUG.

+0

Oui, c'est exactement ce que les macros sont là pour !! – Newtopian

+6

Ceci est dangereux et sujet aux erreurs. 'int x = 0; LOG (x + = 2); use (x); 'se comportera différemment si le mode" release "ou" debug "est activé. – LiraNuna

+2

Oui, ce sera le cas. Rien ne vient gratuitement dans ce monde. – sharptooth

1

J'ai déjà fait quelque chose comme ça avec le préprocesseur.

#ifndef DEBUG 
#define debugPrint 
#endif 

Essentiellement qui supprimera toutes les lignes de débogage

+1

Err, ne serait-ce pas le valide 'debugPrintf ("bonjour"); dans le plutôt invalide '("bonjour");' ? – paxdiablo

+1

@Pax, c'est parfaitement valide. – strager

+1

Mais celui qui est susceptible de déclencher un avertissement. '(vide) (" bonjour ")' semble plus approprié. C'est faux, cependant: debugPrint (GetFoo()) appellera toujours GetFoo() avec cette macro, qui n'a pas été explicitement demandée. – MSalters

7

font de la ligne de fonction, et à l'intérieur de la fonction ont les #ifdef de, comme ceci:

inline void debugPrint(whatever_t wtvr) 
{ 
    #ifdef DEBUG 
     Logger::log(wtvr); 
    #endif 
} 

De cette façon, l'optimiseur dépouiller les fonction vide tout en gardant le code propre.

+2

Est-ce que cela garantira que le paramètre de fonction ne sera pas évalué? – sharptooth

+0

Cela ne va pas aider avec l'autre exigence (que s'il y a du code qui doit être évalué pour calculer wtvr ne sera pas généré non plus) –

+3

@sharptooth, Ils doivent être évalués avec cette solution. Cependant, si l'évaluation modifie le fonctionnement du programme (c'est-à-dire les effets secondaires), le problème est que les appels à la fonction de journalisation peuvent faire plus que simplement se connecter. – strager

1

#ifdef _DEBUG 
#define debugPrint(x) _debugPrint(x) 
void _debugPrint(int foo) { 
    // debugPrint implementation 
} 
#else 
#define debugPrint(x) 
#endif 
2

La réponse de @ sharptooth est bonne. Un changement mineur que je fais normalement, cependant, est de désactiver le débogage si le NDEBUG macro est pas définie, plutôt que si un débogage macro est défini:

#ifndef NDEBUG 
   #define LOG(x) debugPrint(x) 
#else 
   #define LOG(x) 
#endif 

Lorsque la NDEBUG macro est définie, C assert s, que j'ai tendance à utiliser assez libéralement pour affirmer des choses comme des conditions préalables et des post-conditions ou même pour aider à clarifier le résultat d'une logique complexe, abandonner aussi la compilation. C'est une macro standard pour "pas de débogage". Et, la macro NDEBUG doit déjà être définie dans les versions de version.

Voir: http://www.opengroup.org/onlinepubs/009695399/functions/assert.html

Questions connexes