2

I would like to display some log messages when debugging. One option is to use the very ugly

#ifdef DEBUG std::cout << "I'm in debug mode!\n"; #endif 

In the JUCE library, there is a nice macro that outputs text to the debugging pane

DBG("I'm in debug mode!") 

The juce solution also allows you to do neat stuff like the following that would be desirable

int x = 4; DBG(String("x=") + String(x)) 

I would like to know if a similarly neat method exists in std:: or boost::

7
  • The thingy at the bottom of the xcode window :) Commented May 4, 2012 at 11:28
  • Well, not everyone uses xcode, and your question makes no mention of it. ;) Commented May 4, 2012 at 11:29
  • Ideally it would be the thigy at the bottom of xcode or Visual studio ;) Commented May 4, 2012 at 11:29
  • See, now we're getting somewhere. But what if I'm coding in Emacs, which doesn't have a debug pane? My point is there is not always a debug pane. And even when there is, the way in which you write to it differs (xcode just prints the standard output stream to the debug pane I believe, but Visual Studio requires you to use the DebugOutputString() function. So making a single universal solution is pretty much impossible. :) Commented May 4, 2012 at 11:32
  • The one in JUCE works nicely on both platforms Commented May 4, 2012 at 11:35

3 Answers 3

6

Why not just write your own:

#ifdef DEBUG #define DBG(x) std::cout << x; #else #define DBG(x) #endif 

For namespaces

namespace DBG { inline void DBG(const char* x) { #ifdef DEBUG std::cout << x; #endif } } 
Sign up to request clarification or add additional context in comments.

7 Comments

Is there any way to put that into a namespace?
@learnvst: macro's don't fit in namespaces, but the macro version allows this: DBG("first: " << first << ", second: " << second);
@stefaanv I know the behavior is not the same, but there's really no other way to have it in a namespace.
I now have the solution I want. I use the second example above, but taking std::string as the function input. I can then use boost::lexical_cast when using int x = 4; utils::DBG("abc" + boost::lexical_cast<std::string>x) to add numeric values if needed. I'll roll with that unless someone suggests an even neater way to do this.
@Luchian: I agree. I just showed the OP, that he still has to make a choice between both, which apparently, he did. (although, I would not want to see lexical_cast all over my logs)
|
2

If you want something like printf, you should use a bit another macros:

void DebugPrintLn(const char* format, ...); inline void Nothing(...) {} #ifdef DEBUG #define DBG DebugPrintLn #else #define DBG Nothing // Or __noop on Visual C++ #endif 

Using Nothing is portable, but arguments still computed (__noop guarantees that any of argument will be not computed, VC++ specific). Better if you can use macros variable arguments (both available on GCC and latest VC++): you may even skip any argument computation in portable way:

#ifdef DEBUG #define DBG(...) DebugPrintLn(__VAR_ARGS__) #else #define DBG(...) ((void)0) #endif 

In any case, you use it the same way:

DBG("Lucky day: %s %i", "Friday", 13); 

Comments

0

I have also written my own portable TRACE macro. I share it here:

#ifdef ENABLE_TRACE # ifdef _MSC_VER # include <windows.h> # include <sstream> # define TRACE(x) \ do { std::stringstream s; s << (x); \ OutputDebugString(s.str().c_str()); \ } while(0) # else # include <iostream> # define TRACE(x) std::clog << (x) # endif // or std::cerr << (x) << std::flush #else # define TRACE(x) #endif 

example:

#define ENABLE_TRACE //can depend on _DEBUG or NDEBUG macros #include "my_above_trace_header.h" int main (void) { int v1 = 123; double v2 = 456.789; TRACE ("main() v1="<< v1 <<" v2="<< v2 <<'\n'); } 

Any improvements/suggestions/contributions are welcome ;-)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.