Question

One can remove all calls to printf() using #define printf. What if I have a lot of debug prints like std::cout << x << endl; ? How can I quickly switch off cout << statements in a single file using preprocessor?

Was it helpful?

Solution

NullStream can be a good solution if you are looking for something quick that removes debug statements. However I would recommend creating your own class for debugging, that can be expanded as needed when more debug functionality is required:

class MyDebug
{
    std::ostream & stream;
  public:
    MyDebug(std::ostream & s) : stream(s) {}
#ifdef NDEBUG
    template<typename T>
    MyDebug & operator<<(T& item)
    {
      stream << item;
      return *this;
    }
#else
    template<typename T>
    MyDebug & operator<<(T&)
    {
      return *this;
    }
#endif
};

This is a simple setup that can do what you want initially, plus it has the added benefit of letting you add functionality such as debug levels etc..

Update: Now since manipulators are implemented as functions, if you want to accept manipulators as well (endl) you can add:

MyDebug & operator<<(std::ostream & (*pf)(std::ostream&))
{
  stream << pf;
  return *this;
}

And for all manipulator types (So that you don't have to overload for all manipulator types):

template<typename R, typename P>
MyDebug & operator<<(R & (*pf)(P &))
{
  stream << pf;
  return *this;
}

Be careful with this last one, because that will also accept regular functions pointers.

OTHER TIPS

As "unwind" already said, the quick solution is a do-nothing stream. There are better implementations though:

class NullStream {
    public:
    NullStream() { }
    template<typename T> NullStream& operator<<(T const&) { return *this; }
};

You still have a slight issue with std::cout since that's a sequence of three tokens, and you really don't want to redefine std or cout individually. A simple solution is

#ifdef NDEBUG
    #define COUT std::cout
#else
    #define COUT NullStream()
#endif

COUT << "Hello, world" << std::endl;

As a general principle logging to stdout should be avoided - far better to log to a logfile, and then you can use standard configuration tools to change log levels, or turn it off altogether.

Just my $0.02.....

Substitute your debug output statements with something like this:

IFDBG(cout << result << endl);

Then you can define macros accordingly:

#ifdef DEBUG
#  define IFDBG(x) x
#else
#  define IFDBG(x)
#endif

You can probably do a preprocessor hack that defines a new stream-like class, with an instance named cerr, that just does nothing. If you're really lucky, the compiler will see that the function does nothing, and optimize the calls to operator<<() out.

Something like

class NullStream
{
public:
  NullStream();

  NullStream& operator<<(const std::string& text) { return *this; }
  // And operators for other types, too
}
static NullStream cerr;

This is quite the hack though, it's (far) better to go through your source and add proper support for logging.

Define this macro :

#ifdef DEBUG
    #define MY_LOG std::cout
#else
    #define MY_LOG if(false) std::cout
#endif

This macro advantage is in compiler optimization

If expressions placed inside those IFs are constant and determinable at the time of compilation, then you may be almost sure that the compiler has already removed them off the code for you... https://stackoverflow.com/a/14657645/5052296

Defining a macro that replaces cout is not something you should upload to your VCS, but if you just do it temporarily during debugging, I think it serves its place. So you can just replace cout by ostream(0) like

#ifdef NDEBUG
#define cout ostream(0).flush()
#endif

This way, it works with both std::cout and plain cout, and ostream is available when including <iostream>. Writing into a ostream(0) is a no-op. The flush function call is done so that you get a non-const reference to it (so it also binds to non-member operator<< that's used for outputting std::string and others). As its type is ostream, it should behave exactly like cout.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top