Looking at some macros of Qt Test Framework like QCOMPARE
, this is the code:
#define QCOMPARE(actual, expected) \
do {\
if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
return;\
} while (0)
As you can see, there is a while loop. I found the same thing inside CryEngine Unit Testing framework too. My question is simple: is there any reason to use that loop or maybe is something left there from an old implementation?
You'll notice that the while
condition is always false, so there is no actual loop. It's a common trick to have blocks in preprocessor macros and still require a semicolon at the end (so using the macro feels like using a function, and to not confuse some indenters). That is to say,
QCOMPARE(foo, bar); // <-- works
QCOMPARE(foo, bar) // <-- will not work.
This is most useful in the context of if
and else
, where
if(something)
QCOMPARE(foo, bar);
else
do_something();
will expand to
if(something)
do stuff() while(0);
else
do_something();
which works, whereas a multiline macro with a block and without the loop construct would expand to
if(something)
{ stuff() }; // <-- if statement ends here
else // <-- and this is at best a syntax error.
do_something();
which does not.