43 votes

Comment créer une fonction de débogage uniquement qui prend une liste d'arguments variables? J'aime printf ()

J'aimerais créer une fonction de journalisation de débogage avec les mêmes paramètres que printf . Mais celui qui peut être supprimé par le pré-processeur lors des builds optimisés.

Par exemple:

 Debug_Print("Warning: value %d > 3!\n", value);
 

J'ai examiné les macros variadiques, mais celles-ci ne sont pas disponibles sur toutes les plateformes. gcc soutient, msvc ne les soutient pas.

25voto

James Devlin Points 6699

Je le fais toujours à l'ancienne, en définissant une macro (XTRACE, ci-dessous) qui correspond à un appel no-op ou à un appel de fonction avec une liste d'arguments variables. En interne, appelez vsnprintf pour conserver la syntaxe printf:

 #include <stdio.h>

void XTrace0(LPCTSTR lpszText)
{
   ::OutputDebugString(lpszText);
}

void XTrace(LPCTSTR lpszFormat, ...)
{
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[512]; // get rid of this hard-coded buffer
    nBuf = _vsntprintf(szBuffer, 511, lpszFormat, args);
    ::OutputDebugString(szBuffer);
    va_end(args);
}
 

Puis un commutateur typique #ifdef:

 #ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
 

Cela peut être nettoyé un peu, mais c’est l’idée de base.

22voto

snstrand Points 161

C'est ainsi que je débogue les impressions en C ++. Définissez 'dout' comme ceci:

 #ifdef DEBUG
#define dout cout
#else
#define dout 0 && cout
#endif
 

Dans le code, j'utilise 'dout' comme 'cout'.

 dout << "in foobar with x= " << x << " and y= " << y << '\n';
 

Si le préprocesseur remplace 'dout' par '0 && cout', notez que << a une priorité supérieure à && et que l'évaluation du court-circuit de && rend la ligne entière évaluée à 0. Puisque le 0 n'est pas utilisé, le compilateur ne génère aucun code. pour cette ligne.

11voto

Graeme Perrow Points 22249

Voici quelque chose que je fais en C / C ++. Tout d'abord, vous écrivez une fonction qui utilise les éléments varargs (voir le lien dans l'affichage de Stu). Alors fais quelque chose comme ça:

 
 int debug_printf( const char *fmt, ... );
 #if defined( DEBUG )
  #define DEBUG_PRINTF(x) debug_printf x
 #else
   #define DEBUG_PRINTF(x)
 #endif

 DEBUG_PRINTF(( "Format string that takes %s %s\n", "any number", "of args" ));
 

Tout ce que vous devez vous rappeler est d'utiliser un double parent lorsque vous appelez la fonction de débogage, et toute la ligne sera supprimée dans du code non-DEBUG.

4voto

Mat Noguchi Points 851

Une autre façon amusante de remplacer les fonctions variadiques est la suivante:

 #define function sizeof
 

3voto

Ferruccio Points 51508

@CodingTheWheel:

Il y a un léger problème avec votre approche. Considérons un appel comme

XTRACE("x=%d", x);

Cela fonctionne bien dans la version debug, mais dans la version de publication, il sera étendu à:

("x=%d", x);

Ce qui est parfaitement légitime de C et de compiler et l'habitude de courir sans effets secondaires, mais génère du code inutile. L'approche que j'ai l'habitude de l'utiliser pour éliminer ce problème, c'est:

  1. Faire de la XTrace fonction retourne un int (juste retour de 0, la valeur de retour n'a pas d'importance)

  2. Modifier les #define dans le #else clause:

    0 && XTrace
    

Maintenant, la version sera étendue à d':

0 && XTrace("x=%d", x);

et tout décent optimiseur de jeter le tout depuis l'évaluation de court-circuit qui aurait empêché quoi que ce soit après le && de jamais être exécutée.

Bien sûr, comme je l'ai écrit la dernière phrase, j'ai réalisé que peut-être la forme originale peut être optimisé à l'écart de trop et dans le cas d'effets secondaires, tels que les appels de fonction passés en paramètres à XTrace, il pourrait être une meilleure solution, car il fera en sorte que les versions debug et release va se comportent de la même.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X