Introduction

Les développeurs se retrouvent souvent dans le besoin d’un mécanisme de journalisation fiable à des fins de débogage. Cependant, maintenir un code efficace lors de la production peut être un défi, surtout lorsque la journalisation verbale peut affecter les performances. Une question courante se pose : Comment créer une fonction de débogage qui ne supporte qu’une liste d’arguments variables, semblable à printf() ?

Dans cet article, nous explorerons une solution simple qui utilise les directives du préprocesseur C/C++ pour créer une fonction de journalisation de débogage qui peut être éliminée lors des builds optimisés tout en maintenant la flexibilité des entrées variables.

Création de la Fonction de Journalisation de Débogage

Étape 1 : Définir la Signature de la Fonction

Nous voulons que notre fonction de journalisation accepte une chaîne de format et un nombre variable d’arguments. La signature de fonction de style printf nous permet de formater des chaînes dynamiquement. Voici une structure de base de la fonction souhaitée :

void XTrace(LPCTSTR lpszFormat, ...);

Étape 2 : Utilisation des Arguments Variables

Pour atteindre la fonctionnalité d’arguments variables, nous pouvons utiliser les macros va_list, va_start et va_end fournies par la bibliothèque standard C. Cela nous permet de traiter les arguments passés à XTrace.

Voici comment vous pouvez mettre cela en œuvre :

#include <stdio.h>

void XTrace(LPCTSTR lpszFormat, ...) {
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[512]; // Pensez à utiliser une allocation dynamique à la place
    nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
    ::OutputDebugString(szBuffer); 
    va_end(args);
}

Éléments Clés du Code :

  • va_list args : Ceci est utilisé pour stocker la liste d’arguments.
  • va_start(args, lpszFormat) : Ceci initialise args pour récupérer les arguments après lpszFormat.
  • _vsnprintf : Cette fonction formate la chaîne en utilisant la liste d’arguments et l’écrit dans un tampon.
  • OutputDebugString : Sort la chaîne formatée dans la fenêtre de sortie du débogueur.

Étape 3 : Compilation Conditionnelle

Pour s’assurer que la fonction de débogage est supprimée dans les builds optimisés, nous pouvons utiliser des directives de préprocesseur. En définissant une macro basée sur un flag de débogage, nous pouvons contrôler l’inclusion ou l’exclusion de notre fonction de journalisation.

Exemple de Configuration :

#ifdef _DEBUG
#define XTRACE XTrace
#else
#define XTRACE
#endif
  • La macro XTRACE pointera vers la fonction XTrace réelle lors de la compilation en mode débogage. Dans les builds optimisés (lorsque _DEBUG n’est pas défini), XTRACE deviendra une instruction vide, éliminant efficacement tout code de journalisation de débogage.

Rassembler le Tout

Voici l’implémentation complète pour plus de clarté :

#include <stdio.h>
#include <stdarg.h>
#include <Windows.h> // ou <Linux/string.h> selon la plateforme

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

void XTrace(LPCTSTR lpszFormat, ...) {
    va_list args;
    va_start(args, lpszFormat);
    int nBuf;
    TCHAR szBuffer[512];
    nBuf = _vsnprintf(szBuffer, 511, lpszFormat, args);
    ::OutputDebugString(szBuffer);
    va_end(args);
}

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

Vous pouvez désormais utiliser la macro XTRACE dans votre code comme suit :

XTRACE("Avertissement : valeur %d > 3!\n", value);

Conclusion

Créer une fonction de journalisation de débogage uniquement en C/C++ qui peut accepter des arguments variables est non seulement faisable, mais peut également être géré efficacement grâce à des directives de préprocesseur. Cette technique permet de garder votre code de production propre et efficace en termes de performances.

Maintenant, vous pouvez déboguer vos applications efficacement sans compromettre les performances dans l’environnement de production !