Цикл while внутри модуля модульного тестирования

Рассматривая некоторые макросы Qt Test Framework, такие как QCOMPAREэто код:

#define QCOMPARE(actual, expected) \
do {\
if (!QTest::qCompare(actual, expected, #actual, #expected, __FILE__, __LINE__))\
return;\
} while (0)

Как видите, есть цикл while. То же самое я обнаружил и в платформе CryEngine Unit Testing. Мой вопрос прост: есть ли причина использовать этот цикл или, может быть, что-то осталось от старой реализации?

2

Решение

Вы заметите, что while условие всегда ложно, поэтому нет фактического цикла. Это распространенная уловка — иметь блоки в макросах препроцессора и по-прежнему требовать точку с запятой в конце (поэтому использование макроса похоже на использование функции, и не путает некоторые отступы). То есть

QCOMPARE(foo, bar); // <-- works
QCOMPARE(foo, bar)  // <-- will not work.

Это наиболее полезно в контексте if а также else, где

if(something)
QCOMPARE(foo, bar);
else
do_something();

будет расширяться до

if(something)
do stuff() while(0);
else
do_something();

который работает, тогда как многострочный макрос с блоком и без конструкции цикла будет расширяться до

if(something)
{ stuff() }; // <-- if statement ends here
else           // <-- and this is at best a syntax error.
do_something();

что нет.

6

Другие решения