Reputation: 26281
I've been inspecting someone's code and I encountered this:
#else //If not in Debug mode
#define LOG_WARNING(str) do { (void)sizeof(str); } while(0)
#define LOG_INFO(str) do { (void)sizeof(str); } while(0)
// ... More #define directives
#endif
Apparently, do { (void)sizeof(str); } while(0)
is carefully written so the directive can be completely ignored by the compiler.
How does this work?
Upvotes: 3
Views: 485
Reputation: 254431
The operand of sizeof
is an unevaluated, so this ensures that there is no work to be done at run time. The macro just ignores a constant value; the compiler can see that it has no effect, so should generate no code from it.
The advantage over doing nothing at all is that the compiler still checks that the argument is a valid expression; you won't accidentally break the debug build when changing the code and only compiling for release.
The advantage over (void)str
, mentioned in the comments, is that that would evaluate the expression, and the compiler might not be able to eliminate it, since it there might be side effects. For example:
extern std::string get_message(int code);
LOG_INFO(get_message(code)); // -> (void)get_message(code);
in a release build would call the function and ignore the result, impacting performance.
Upvotes: 4