简体   繁体   中英

Clang: expression result unused with ternary operator

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)

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM