Рассматривая некоторые макросы 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. Мой вопрос прост: есть ли причина использовать этот цикл или, может быть, что-то осталось от старой реализации?
Вы заметите, что 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();
что нет.