1

This is a follow up to this question:

What's the use of do while(0) when we define a macro?

This macro is used in the Qt unit tests:

#define QVERIFY2(statement, description) \
do {\
    if (statement) {\
        if (!QTest::qVerify(true, #statement, (description), __FILE__, __LINE__))\
            return;\
    } else {\
        if (!QTest::qVerify(false, #statement, (description), __FILE__, __LINE__))\
            return;\
    }\
} while (0)

It verifies the statement, and if it is false it produces an error message with the given description.

My question is, what could be the reason for the if - else statement inside? Why isn't it defined simply like this?

#define QVERIFY2(statement, description) \
do {\
    if (!QTest::qVerify(statement, #statement, (description), __FILE__, __LINE__))\
        return;\
    }\
} while (0)

I suspect that the explaination is of the same sort as in the refered question. Any ideas?

UPDATE

To give some more context, the following variant of the macro, without the description, is also defined:

#define QVERIFY(statement) \
do {\
    if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__))\
        return;\
} while (0)

This would suggest, that the trick somehow concerned with the description parameter.

Community
  • 1
  • 1
Gábor Angyal
  • 2,225
  • 17
  • 27
  • Based solely on what you have posted, the shorter version should work as well as the longer version. – R Sahu Feb 27 '15 at 20:17
  • Probably to improve clarity. This way we know that `statement` is a boolean (`if(statement)`), otherwise we couldn't be sure `qVerify(statement..`, without looking at `qVerify` definition – hlscalon Feb 27 '15 at 20:24
  • 3
    One thing that macro does is ensure that `statement` is evaluated before `description`. – rici Feb 27 '15 at 20:25
  • @rici it also ensures that `description` is evaluated whichever way the branch goes. – Mark Ransom Feb 27 '15 at 20:28
  • @1nflktd, I thought the same, but could have just done `if (!QTest::qVerify((statement) != 0, ...` – franji1 Feb 27 '15 at 20:29
  • @rici Nice insight. You should post it as an answer. – Gábor Angyal Feb 27 '15 at 20:30
  • @MarkRansom: `description` would be evaluated by the suggested simpler call, too. Just not in order. – rici Feb 27 '15 at 20:31
  • I'm guessing that this is historical thing (I didn't found history earlier then qt4.5 so I'm no sure). Probably somewhere in the past there was no else statement and this "if" prevented evaluation of description. Then someone decided that passed verification should also be processed and added else statement. – Marek R Feb 27 '15 at 20:33
  • @MarekR Seems unlikely because of the alternative macro in the simpler form. – Gábor Angyal Feb 27 '15 at 20:35
  • @rici I suggest that the `if` is for the reason you state, and the `else` is for the reason I state. – Mark Ransom Feb 27 '15 at 20:42

2 Answers2

4

One possible explanation is that the macro ensures that statement is evaluated before description.

rici
  • 234,347
  • 28
  • 237
  • 341
1

An important difference, if QTest::qVerify's first parameter has type bool, is that there are more types that are contextually convertible to bool than there are that are implicitly convertible to bool.

Given

struct S { explicit operator bool(); } s;
void f(bool);

the call f(s) is invalid, but if (s) f(true); else f(false); is valid.

However, given the definition QVERIFY macro you show in the question, it does seem likely that this was never a real consideration.