Matias Cicero
Matias Cicero

Reputation: 26281

sizeof operator in #define directives

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

Answers (1)

Mike Seymour
Mike Seymour

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

Related Questions