Reputation: 431
To print debug messages in my program, I have a that can be used like this:
DBG(5) << "Foobar" << std::endl;
5 means the level of the message, if the debug level is smaller than 5, it won't print the message. Currently it is implemented like:
#define DBG(level) !::Logger::IsToDebug((level)) ? : ::Logger::Debug
Basically IsToDebug
checks if the message should be printed, and returns true when it should. Logger::Debug
is an std::ostream. This works with gcc and clang too, however clang generates expression result unused warnings. According to this email this doesn't like to change either.
Prefixing it with (void)
doesn't work, it will only cast the thing before the ?
, resulting in a compilation error (void can't be converted to bool, obviously). The other problem with this syntax that it uses a gcc extension.
Doing things like #define DBG(x) if (::Logger::IsToDebug((x))) ::Logger::Debug
solves the problem, but it's a sure way break your program (if (foo) DBG(1) << "foo"; else ...
) (and I can't put the whole thing into a do { ... } while(0)
due to how the macro is called.)
The only more or less viable solution I came up with is this (assuming IsToDebug
returns either 0 or 1):
#define DBG(level) for(int dbgtmpvar = ::Logger::IsToDebug((level)); \
dbgtmpvar > 0; --dbgtmpvar) ::Logger::Debug
Which seems like an overkill (not counting it's runtime overhead)
Upvotes: 3
Views: 1401
Reputation: 361362
I think you should use ternary operator, as it is defined in the Standard, rather than compiler extension. To use the Standard ternary operator, you've to provide the second expression as well. For that, you can define a stream class, deriving from std::ostream
which doesn't print anything to anywhere. Object of such a class can be used as second expression.
class oemptystream : std::ostream
{
//..
};
extern oemptystream nout; //declaration here, as definition should go to .cpp
then
#define DBG(level) ::Logger::IsToDebug((level))? nout : ::Logger::Debug
Now if you use this macro, then at runtime, the expression would reduce to either this:
nout << "message";
Or this,
::Logger::Debug << "message";
Either way, it is pretty much like this:
std::cout << "message";
So I hope it shouldn't give compiler warning.
Upvotes: 4