What's the reason for this no-op while-loop us

2019-07-15 12:31发布

问题:

I'm reviewing a codebase where assert macro is expanded like this in non-debug configurations:

#define assert( what ) while( 0 )( ( void )1 )

which I don't quite get. Obviously the goal is to have a no-op. Then why not expand into an empty string?

#define assert( what )

What's the reason for this no-op loop?

回答1:

Most likely to avoid compiler warnings. Check whether this code provokes a warning about an empty statement:

if (foo);

If it does, then do you want the same warning in release mode for the following code?

if (foo) assert(what);

C99 (which is relevant to C++11) also says that assert expands "to a void expression". IIRC, whitespace alone isn't an expression, even though whitespace followed by a semi-colon is an expression-statement. Good old BNF grammar.

By the way, this definition of assert is not standard-conforming. C89 and C99 both say that when NDEBUG is defined, then assert is defined as:

#define assert(ignore) ((void)0)

I'm not sure whether the authors consider it an important requirement, but a program could for example stringify the macro expansion and expect a particular result.



回答2:

To gobble up the semicolon, most likely. Whether it's needed or not — I don't think it'll make much difference, but at the same time, it doesn't hurt anything, either.