c++qtunit-testingcryengine

While loop inside unit testing framework


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?


Solution

  • 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.