tags:

views:

100

answers:

3

Hi.

Is there a way to define/undefine debug messages using std::cout whenever inside a program?

I am aware that there are such things such as #define, #ifndef, but I was thinking is there a cleaner way to having a variable say:

# debug ON

That prints all of my debug data (using std::cout). Consequently, we'll have code like this for debug:

#ifndef DEBUG
// do something useful
#endif

I find the above code cumbersome when you write 100s of debug code.

Thanks!

Carlo

+5  A: 

Probably not. I would recommend using a logging library. I'm not sure what the best option is for C++ anymore, but I've used log4cpp in the past and found it pretty good.

EDIT: I assume on the fly means @ runtime. If you just need it to be a compile time flag, then Gianni's answer is probably easiest to implement. Logging libraries give you a lot of flexibility and allow reconfiguration @ runtime though.

SB
+1. log4cpp is kind of old; I'd recommend investigating log4cxx, one of the Boost.Log candidates, or Pantheios.
Josh Kelley
Thanks I'll lookinto log4cpp
Carlo del Mundo
@Carlo - you might want to check into the ones suggested by Josh. I know log4cpp is kind of old.
SB
+2  A: 
#ifdef DEBUG
#define DEBUG_MSG(str) do { std::cout << str << std::endl; } while( false )
#else
#define DEBUG_MSG(str) do { } while ( false )
#endif

int main()
{
    DEBUG_MSG("Hello" << ' ' << "World!" << 1 );
    return 0;
}
Gianni
You've typo-ed in your second `#define`.
Stephen
@Stephen Thanks.
Gianni
Thanks! I think this is what I was looking for!
Carlo del Mundo
This isn't something you can change during runtime. If by "on the fly" you mean at compile time, then this is a very simple and good answer for your needs. If you need to change it @ runtime, log libraries are designed to do this and be configurable via some file rather than compile time flags.
SB
@SB I understood "on the fly" to mean compile-time since it was implied by his use of `#ifndef debug`
Gianni
+3  A: 

Some logging libraries are pretty heavy weight unless you have complex logging needs. Here's something I just knocked together. Needs a little testing but might meet your requirements:

#include <cstdio>
#include <cstdarg>

class CLog
{
public:
    enum { All=0, Debug, Info, Warning, Error, Fatal, None };
    static void Write(int nLevel, const char *szFormat, ...);
    static void SetLevel(int nLevel);

protected:
    static void CheckInit();
    static void Init();

private:
    CLog();
    static bool m_bInitialised;
    static int  m_nLevel;
};

bool CLog::m_bInitialised;
int  CLog::m_nLevel;

void CLog::Write(int nLevel, const char *szFormat, ...)
{
    CheckInit();
    if (nLevel >= m_nLevel)
    {
        va_list args;
        va_start(args, szFormat);
        vprintf(szFormat, args);
        va_end(args);
    }
}
void CLog::SetLevel(int nLevel)
{
    m_nLevel = nLevel;
    m_bInitialised = true;
}
void CLog::CheckInit()
{
    if (!m_bInitialised)
    {
        Init();
    }
}
void CLog::Init()
{
    int nDfltLevel(CLog::All);
    // Retrieve your level from an environment variable, 
    // registry entry or wherecer
    SetLevel(nDfltLevel);
}

int main()
{
    CLog::Write(CLog::Debug, "testing 1 2 3");
    return 0;
}
Michael J
Thanks! I'll look into this. This looks suitable for my small program!
Carlo del Mundo
Doesn't do any locking. If your program is heavily multithreaded you might need that.
Michael J