2013-04-16 4 views
5

Ich verwende boost::log als Logger für mein C++ - Programm. Während der Entwicklung verwende es mir oft diese Art und Weise, zum Beispiel:Wie Log-Debugging-Anweisungen aus einem Programm zu entfernen

#define LOG(severity) BOOST_LOG_SEV(boost::logger::get(), (severity)) 
#define LOG_ERR LOG(Severity::error) 
#define LOG_INFO LOG(Severity::info) 
#define LOG_DEBUG LOG(Severity::debug) 

wo BOOST_LOG_SEV die Anlage von boost::log vorgesehen ist, während LOG, LOG_ERROR, LOG_INFO, LOG_DEBUG Verknüpfungen von mir definiert sind.

Kurz gesagt, BOOST_LOG_SEV vergleicht dynamisch den aktuellen Debugging-Schweregrad mit dem Schweregrad, der an das Makro übergeben wurde, um zu entscheiden, ob die Ausgabe ausgegeben werden soll oder nicht.

Dies ist ein Beispiel für ein Programm, das das obige Makros für Debugging-Zwecke verwenden:

// set at compile time 
#define MAX_LOG_SEVERITY Severity::debug 

int main() { 
    // Print all the messages with a 
    // Severity <= MAX_LOG_SEVERITY defined before compiling 
    boost::log::set_severity(boost::logger::get(), MAX_LOG_SEVERITY); // set_severity() is fictitious just to give you an idea 

    // bool err = ... 
    if (err) 
     LOG_ERR << "An error occurred"; 
    else 
     LOG_INFO << "Okay; 
    LOG_DEBUG << "main() called"; 
} 

Nun, wenn das Programms für eine Produktionsumgebung Freigabe, Debugging-Meldungen mit einer Severity::debug Ebene nicht wirklich Sinn machen. Ich konnte sie vor der Ausgabe verbergen, indem ich einfach MAX_LOG_SEVERITY auf Severity::info verringerte, aber das Problem ist, dass die Aufrufe von LOG_DEBUG nicht aus dem ausführbaren Code entfernt werden. Dies wirkt sich sowohl auf die Effizienz als auch auf die Objektgröße negativ aus.

Der Code ist voll von Protokollanweisungen und ich möchte wirklich die einfache Verwendung von operator<<() beibehalten.

Ohne diese Aussagen selbst zu berühren, gibt es eine bessere Makrodefinition/Trick für LOG_DEBUG, die den Pre-Prozessor oder den Compiler (während seiner Optimierungen) „überspringen“ oder „Entfernen“, um die Debugging-Anweisungen machen würden, wenn MAX_LOG_SEVERITY eingestellt ist die Severity::debug Konstante?

Antwort

6

Während ich keine Garantie geben kann, so etwas wie dies funktionieren könnte. Es hängt davon ab, was Ihr Optimierer tut und ob Sie Nebenwirkungen in den Parametern für den Operator < < haben oder nicht.

#ifdef NO_LOG_DEBUG 

static class DevNull 
{ 
} dev_null; 

template <typename T> 
DevNull & operator<<(DevNull & dest, T) 
{ 
    return dest; 
} 

#define LOG_DEBUG dev_null 

#else 

#define LOG_DEBUG LOG(Severity::debug) 

#endif 
-2

Deaktiviert alle Optimierungen im Programm und beschleunigt die Kompilierung.

/Od oder boot_log_stop

2

@ MartinShobe die akzeptierte Antwort funktioniert auf:

  • g ++ (4.7.2) mit -O1 und höher
  • Klirren ++ (3.4) mit -O2 und höher
  • Visual Studio (2008) mit Linkerflagge /OPT:REF
Verwandte Themen